From 5dfc561e627479db9f9776ff887d10f4df354484 Mon Sep 17 00:00:00 2001 From: makslevental Date: Fri, 2 Aug 2024 19:44:14 -0500 Subject: [PATCH 01/12] [wip] fork mlir-aie ops --- compiler/plugins/target/AMD-AIE/aie/AIE.td | 33 + .../plugins/target/AMD-AIE/aie/AIEAttrs.td | 165 ++ .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 1984 +++++++++++++++++ .../plugins/target/AMD-AIE/aie/AIEDialect.h | 391 ++++ .../plugins/target/AMD-AIE/aie/AIEEnums.h | 19 + .../target/AMD-AIE/aie/AIEInterfaces.td | 139 ++ .../AMD-AIE/aie/AIENormalizeAddressSpaces.td | 30 + compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 1970 ++++++++++++++++ .../target/AMD-AIE/aie/AIETargetModel.cpp | 709 ++++++ .../target/AMD-AIE/aie/AIETargetModel.h | 529 +++++ .../plugins/target/AMD-AIE/aie/AIETypes.td | 41 + compiler/plugins/target/AMD-AIE/aie/AIEX.td | 816 +++++++ .../target/AMD-AIE/aie/AIEXDialect.cpp | 359 +++ .../plugins/target/AMD-AIE/aie/AIEXDialect.h | 23 + .../aie/AMDAIEAssignBufferAddressesBasic.cpp | 2 +- .../aie/AMDAIEAssignBufferDescriptorIDs.cpp | 2 +- .../AMD-AIE/aie/AMDAIEAssignLockIDs.cpp | 2 +- .../AMD-AIE/aie/AMDAIECoreToStandard.cpp | 2 +- .../AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp | 2 +- .../target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp | 4 +- .../AMD-AIE/aie/AMDAIELocalizeLocks.cpp | 2 +- .../aie/AMDAIENormalizeAddressSpaces.cpp | 2 +- .../aie/AMDAIEObjectFifoStatefulTransform.cpp | 2 +- .../target/AMD-AIE/aie/AMDAIEXToStandard.cpp | 2 +- .../plugins/target/AMD-AIE/aie/CMakeLists.txt | 69 +- compiler/plugins/target/AMD-AIE/aie/Passes.h | 2 +- 26 files changed, 7248 insertions(+), 53 deletions(-) create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIE.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEDialect.h create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEEnums.h create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEOps.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETypes.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEX.td create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h diff --git a/compiler/plugins/target/AMD-AIE/aie/AIE.td b/compiler/plugins/target/AMD-AIE/aie/AIE.td new file mode 100644 index 000000000..b9fbc9ef3 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIE.td @@ -0,0 +1,33 @@ +//===- AIE.td ----------------------------------------------*- tablegen -*-===// +// +// 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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIE_BASE +#define AIE_BASE + +include "mlir/IR/OpBase.td" + +def AIE_Dialect : Dialect { + let name = "aie"; + let cppNamespace = "::xilinx::AIE"; + let description = [{ + + This is a dialect for describing netlists of AIE components in a + Versal device. It focuses on representing logical stream connections + between cores and DMAs, along with the implementation of those logical + connections in the various switch components. In the dialect, a + switch is referred to as `switchbox` to avoid confusion with the + `switch` keyword in C/C++. + + }]; + let useDefaultTypePrinterParser = 1; + let useDefaultAttributePrinterParser = 1; +} + +#endif // AIE_BASE \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td new file mode 100644 index 000000000..e0858d244 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td @@ -0,0 +1,165 @@ +//===- AIEAttrs.td -----------------------------------------*- tablegen -*-===// +// +// 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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIE_ATTRS +#define AIE_ATTRS + +include "AIE.td" + +include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/EnumAttr.td" + +//===----------------------------------------------------------------------===// +// AIE attributes. +//===----------------------------------------------------------------------===// + +def CoreWire: I32EnumAttrCase<"Core", 0>; +def DMAWire: I32EnumAttrCase<"DMA", 1>; +def FIFOWire: I32EnumAttrCase<"FIFO", 2>; +def SouthWire: I32EnumAttrCase<"South", 3>; +def WestWire: I32EnumAttrCase<"West", 4>; +def NorthWire: I32EnumAttrCase<"North", 5>; +def EastWire: I32EnumAttrCase<"East", 6>; +def PLIOWire: I32EnumAttrCase<"PLIO", 7>; +def NOCWire: I32EnumAttrCase<"NOC", 8>; +def TraceWire: I32EnumAttrCase<"Trace", 9>; +def ControlWire: I32EnumAttrCase<"Ctrl", 10>; + +def WireBundle: I32EnumAttr<"WireBundle", "Bundle of wires", + [ + CoreWire, DMAWire, FIFOWire, SouthWire, WestWire, NorthWire, + EastWire, PLIOWire, NOCWire, TraceWire, ControlWire + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def CascadeDir: I32EnumAttr<"CascadeDir", "Directions for cascade", + [ + SouthWire, WestWire, NorthWire, EastWire + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def LockAction: I32EnumAttr<"LockAction", "lock acquire/release", + [ + I32EnumAttrCase<"Acquire", 0>, + I32EnumAttrCase<"AcquireGreaterEqual", 2>, + I32EnumAttrCase<"Release", 1>, + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def LockBlocking: I32EnumAttr<"LockBlocking", "lock operation is blocking", + [ + I32EnumAttrCase<"NonBlocking", 0>, + I32EnumAttrCase<"Blocking", 1> + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def AIEArch: I32EnumAttr<"AIEArch", "AIE Architecture", + [ + I32EnumAttrCase<"AIE1", 1>, + I32EnumAttrCase<"AIE2", 2> + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def AIEDevice: I32EnumAttr<"AIEDevice", "AIE Device", + [ + I32EnumAttrCase<"xcvc1902", 1>, + I32EnumAttrCase<"xcve2302", 2>, + I32EnumAttrCase<"xcve2802", 3>, + I32EnumAttrCase<"npu1", 4>, + I32EnumAttrCase<"npu1_1col", 5>, + I32EnumAttrCase<"npu1_2col", 6>, + I32EnumAttrCase<"npu1_3col", 7>, + I32EnumAttrCase<"npu1_4col", 8> + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def ObjectFifoPort: I32EnumAttr<"ObjectFifoPort", + "Ports of an object FIFO", + [ + I32EnumAttrCase<"Produce", 0>, + I32EnumAttrCase<"Consume", 1> + ] + > { + let cppNamespace = "xilinx::AIE"; +} + +def DMAChannelDir: I32EnumAttr<"DMAChannelDir", + "DMA Channel direction", + [ + I32EnumAttrCase<"S2MM", 0>, + I32EnumAttrCase<"MM2S", 1> + ]> { + let cppNamespace = "xilinx::AIE"; +} + +def BDDimLayoutAttr : AttrDef { + let mnemonic = "bd_dim_layout"; + let summary = [{ + Tuple encoding the stride and size of one dimension in an AIE2 n-dimensional + buffer descriptor; + }]; + + let parameters = (ins + "uint16_t" : $size, + "uint32_t" : $stride + ); + + let assemblyFormat = "`<` struct(params) `>`"; +} + +def BDDimLayoutArrayAttr : ArrayOfAttr< + /*dialect*/AIE_Dialect, + /*attrName*/"BDDimLayoutArray", + /*attrMnemonic*/"bd_dim_layout_array", + /*eltName*/BDDimLayoutAttr.cppClassName +>; + +def BDDimLayoutArrayArrayAttr : ArrayOfAttr< + /*dialect*/AIE_Dialect, + /*attrName*/"BDDimLayoutArrayArray", + /*attrMnemonic*/"bd_dim_layout_array_array", + /*eltName*/BDDimLayoutArrayAttr.cppClassName +>; + +def BDPadLayoutAttr : AttrDef { + let mnemonic = "bd_pad_layout"; + let summary = [{ + Tuple encoding number of zeros before and after on that dimension in an AIE2 + n-dimensional buffer descriptor; + }]; + + let parameters = (ins + "uint16_t" : $const_pad_before, + "uint16_t" : $const_pad_after + ); + + let assemblyFormat = "`<` struct(params) `>`"; +} + +def BDPadLayoutArrayAttr : ArrayOfAttr< + /*dialect*/AIE_Dialect, + /*attrName*/"BDPadLayoutArray", + /*attrMnemonic*/"bd_pad_layout_array", + /*eltName*/BDPadLayoutAttr.cppClassName +>; + +#endif // AIE_ATTRS \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp new file mode 100644 index 000000000..e0cd35f14 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -0,0 +1,1984 @@ +//===- AIEDialect.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 +// +// (c) Copyright 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#include "AIEDialect.h" + +#include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/Dialect/MemRef/IR/MemRef.h" +#include "mlir/IR/DialectImplementation.h" +#include "mlir/IR/OpDefinition.h" +#include "mlir/Interfaces/FoldInterfaces.h" +#include "mlir/Transforms/InliningUtils.h" + +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/TypeSwitch.h" + +using namespace mlir; +using namespace xilinx::AIE; + +// Add TableGen'erated dialect definitions (including constructor) +// We implement the initialize() function further below +#include "aie/AIEDialect.cpp.inc" + +namespace { + +struct AIEInlinerInterface : DialectInlinerInterface { + using DialectInlinerInterface::DialectInlinerInterface; + // We don't have any special restrictions on what can be inlined into + // destination regions. Always allow it. + bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned, + IRMapping &valueMapping) const final override { + return true; + } + + // Operations in aie dialect are always legal to inline since they are + // pure. + bool isLegalToInline(Operation *op, Region *, bool wouldBeCloned, + IRMapping &) const final override { + return true; + } + + // Handle the given inlined terminator by replacing it with a new operation + // as necessary. Required when the inlined region has more than one block. + void handleTerminator(Operation *op, Block *newDest) const final override {} + + // Handle the given inlined terminator by replacing it with a new operation + // as necessary. Required when the region has only one block. + void handleTerminator(Operation *op, + ValueRange valuesToRepl) const final override {} +}; + +struct AIEDialectFoldInterface : DialectFoldInterface { + using DialectFoldInterface::DialectFoldInterface; + + /// Registered hook to check if the given region, which is attached to an + /// operation that is *not* isolated from above, should be used when + /// materializing constants. + bool shouldMaterializeInto(Region *region) const final override { + // If this is an AIE::CoreOp region, then insert into it. + return isa(region->getParentOp()); + } +}; + +} // end anonymous namespace + +namespace xilinx::AIE { + +LogicalResult myVerifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) { + std::array maxRanks = op.getArrayAttrMaxRanks(); + if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) && // NOLINT + op.getMixedOffsets().size() != op.getMixedSizes().size()) + return op->emitError( + "expected mixed offsets rank to match mixed sizes rank (") + << op.getMixedOffsets().size() << " vs " << op.getMixedSizes().size() + << ") so the rank of the result type is well-formed."; + if (failed(verifyListOfOperandsOrIntegers( + op, "offset", maxRanks[0], op.getStaticOffsets(), op.getOffsets()))) + return failure(); + if (failed(verifyListOfOperandsOrIntegers( + op, "size", maxRanks[1], op.getStaticSizes(), op.getSizes()))) + return failure(); + if (failed(verifyListOfOperandsOrIntegers( + op, "stride", maxRanks[2], op.getStaticStrides(), op.getStrides()))) + return failure(); + for (int64_t offset : op.getStaticOffsets()) + if (offset < 0 && !ShapedType::isDynamic(offset)) + return op->emitError("expected offsets to be non-negative, but got ") + << offset; + for (int64_t size : op.getStaticSizes()) + if (size < 0 && !ShapedType::isDynamic(size)) + return op->emitError("expected sizes to be non-negative, but got ") + << size; + + return success(); +} + +static VC1902TargetModel VC1902model; +static VE2302TargetModel VE2302model; +static VE2802TargetModel VE2802model; +static NPUTargetModel NPUmodel; +static VirtualizedNPUTargetModel NPUmodel1col(1); +static VirtualizedNPUTargetModel NPUmodel2col(2); +static VirtualizedNPUTargetModel NPUmodel3col(3); +static VirtualizedNPUTargetModel NPUmodel4col(4); + +const AIETargetModel &getTargetModel(Operation *op) { + if (auto t = dyn_cast(op)) + return t.getTargetModel(); + if (auto t = op->getParentOfType()) + return t.getTargetModel(); + + // For backward compatibility, return a basic device model compatible with + // the VCK190 + return VC1902model; +} + +const AIETargetModel &getTargetModel(AIEDevice device) { + switch (device) { + case AIEDevice::xcvc1902: + return VC1902model; + case AIEDevice::xcve2302: + return VE2302model; + case AIEDevice::xcve2802: + return VE2802model; + case AIEDevice::npu1: + return NPUmodel; + case AIEDevice::npu1_1col: + return NPUmodel1col; + case AIEDevice::npu1_2col: + return NPUmodel2col; + case AIEDevice::npu1_3col: + return NPUmodel3col; + case AIEDevice::npu1_4col: + return NPUmodel4col; + } + return VC1902model; +} + +// Walk the operation hierarchy until we find a containing TileElement. +// If no parent is a TileElement, then return null. +static TileElement getParentTileElement(Operation *op) { + auto *parent = op->getParentOp(); + while (!llvm::isa_and_nonnull(parent)) { + if (auto element = llvm::dyn_cast(parent)) + return element; + parent = parent->getParentOp(); + } + return llvm::dyn_cast(parent); +} + +struct UsesAreAccessable { + static LogicalResult verifyTrait(Operation *op) { + auto thisElement = cast(op); + auto thisID = thisElement.getTileID(); + auto users = op->getResult(0).getUsers(); + const auto &targetModel = getTargetModel(op); + for (auto *user : users) { + // AIE.useLock may be used in a device to set the lock's default value + // Allow in a toplevel module for backward compatibility + if (llvm::isa_and_nonnull(user->getParentOp())) + return success(); + if (auto element = getParentTileElement(user)) { + + auto tileID = element.getTileID(); + if (!targetModel.isLegalMemAffinity(tileID.col, tileID.row, thisID.col, + thisID.row)) + return (op->emitOpError("in Column ") + << thisID.col << " and Row " << thisID.row + << " is accessed from an unreachable tile in Column " + << tileID.col << " and Row " << tileID.row) + .attachNote(user->getLoc()) + << "user"; + } else { + // This should probably be caught elsewhere as well. + return op->emitOpError("is accessed outside of a tile") + .attachNote(user->getLoc()) + << "user"; + } + } + return success(); + } +}; + +namespace detail { +/// This class represents the internal storage of the AIE `ObjectFifoType`. +struct AIEObjectFifoTypeStorage : TypeStorage { + /// The `KeyTy` is a required type that provides an interface for the storage + /// instance. This type will be used when uniquing an instance of the type + /// storage. + using KeyTy = MemRefType; + + /// A constructor for the objectFifo type storage instance. + AIEObjectFifoTypeStorage(MemRefType elementType) : elementType(elementType) {} + + /// Define the comparison function for the key type with the current storage + /// instance. This is used when constructing a new instance to ensure that we + /// haven't already uniqued an instance of the given key. + bool operator==(const KeyTy &key) const { return key == KeyTy(elementType); } + + /// Define a construction method for creating a new instance of this storage. + /// This method takes an instance of a storage allocator, and an instance of a + /// `KeyTy`. + static AIEObjectFifoTypeStorage *construct(TypeStorageAllocator &allocator, + const KeyTy &key) { + // Allocate the storage instance and construct it. + return new (allocator.allocate()) + AIEObjectFifoTypeStorage(key); + } + + MemRefType elementType; +}; +} // namespace detail + +AIEObjectFifoType AIEObjectFifoType::get(MemRefType elementType) { + // Call into a helper 'get' method in 'TypeBase' to get an uniqued instance + // of this type. + MLIRContext *ctx = elementType.getContext(); + return Base::get(ctx, elementType); +} + +LogicalResult +AIEObjectFifoType::verify(function_ref emitError, + MemRefType elementType) { + return success(); +} + +mlir::MemRefType AIEObjectFifoType::getElementType() { + // 'getImpl' returns a pointer to the internal storage instance. + return getImpl()->elementType; +} + +namespace detail { +/// This class represents the internal storage of the AIE +/// `ObjectFifoSubviewType`. +struct AIEObjectFifoSubviewTypeStorage : TypeStorage { + /// The `KeyTy` is a required type that provides an interface for the storage + /// instance. This type will be used when uniquing an instance of the type + /// storage. + using KeyTy = MemRefType; + + /// A constructor for the subview type storage instance. + AIEObjectFifoSubviewTypeStorage(MemRefType elementType) + : elementType(elementType) {} + + /// Define the comparison function for the key type with the current storage + /// instance. This is used when constructing a new instance to ensure that we + /// haven't already uniqued an instance of the given key. + bool operator==(const KeyTy &key) const { return key == elementType; } + + /// Define a construction method for creating a new instance of this storage. + /// This method takes an instance of a storage allocator, and an instance of a + /// `KeyTy`. + static AIEObjectFifoSubviewTypeStorage * + construct(TypeStorageAllocator &allocator, const KeyTy &key) { + // Allocate the storage instance and construct it. + return new (allocator.allocate()) + AIEObjectFifoSubviewTypeStorage(key); + } + + MemRefType elementType; +}; +} // namespace detail + +AIEObjectFifoSubviewType AIEObjectFifoSubviewType::get(MemRefType elementType) { + // Call into a helper 'get' method in 'TypeBase' to get a uniqued instance + // of this type. + MLIRContext *ctx = elementType.getContext(); + return Base::get(ctx, elementType); +} + +/// This method is used to verify the construction invariants. +LogicalResult +AIEObjectFifoSubviewType::verify(function_ref emitError, + MemRefType elementType) { + return success(); +} + +MemRefType AIEObjectFifoSubviewType::getElementType() { + return getImpl()->elementType; +} + +/// Parse an instance of a type registered to the AIE dialect. +/// Parse an AIE type in the following forms: +/// AIE-type +/// ::= `objectfifo` `<` type `>` +/// ::= `objectfifosubview` `<` type `>` +static OptionalParseResult aieTypeParser(DialectAsmParser &parser, + StringRef name, Type &result) { + if (name == "objectfifo") { + MemRefType elementType; + SMLoc typeLoc = parser.getCurrentLocation(); + if (parser.parseLess() || parser.parseType(elementType) || + parser.parseGreater()) + return failure(); + + // Check that the type is a MemRef type. + if (!llvm::isa(elementType)) { + parser.emitError(typeLoc, "element type for an objectFifo must be " + "a MemRefType, got: ") + << elementType; + return failure(); + } + + return result = AIEObjectFifoType::get(elementType), success(); + } + + if (name == "objectfifosubview") { + if (parser.parseLess()) + return failure(); + + // Parse the element type of the struct. + MemRefType elementType; + // Parse the current element type. + SMLoc typeLoc = parser.getCurrentLocation(); + if (parser.parseType(elementType)) + return failure(); + + // Check that the type is a MemRefType. + if (!llvm::isa(elementType)) { + parser.emitError(typeLoc, "element type for a subview must be " + "a MemRefType, got: ") + << elementType; + return failure(); + } + + // Parse: `>` + if (parser.parseGreater()) + return failure(); + + return result = AIEObjectFifoSubviewType::get(elementType), success(); + } + + return {}; +} + +/// Parse a type defined by this dialect. +/// Emits an error and returns failure if `name` does not +/// refer to a type defined in this dialect. +static ParseResult parse(Type &result, StringRef name, + DialectAsmParser &parser) { + + if (OptionalParseResult parseResult = aieTypeParser(parser, name, result); + parseResult.has_value()) + return parseResult.value(); + + parser.emitError(parser.getNameLoc(), "unknown AIE dialect type: \"") + << name << "\""; + return failure(); +} + +/// Parse an instance of a type registered to the AIE dialect. +Type AIEDialect::parseType(DialectAsmParser &parser) const { + StringRef name; + Type result; + if (parser.parseKeyword(&name) || parse(result, name, parser)) + return {}; + return result; +} + +/// Print an instance of a type registered to the AIE dialect. +void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { + if (llvm::isa(type)) { + auto objectFifoType = llvm::cast(type); + printer << "objectfifo<"; + printer << objectFifoType.getElementType(); + printer << '>'; + + } else if (llvm::isa(type)) { + auto subviewType = llvm::cast(type); + printer << "objectfifosubview<"; + printer << subviewType.getElementType(); + printer << '>'; + } +} + +void AIEDialect::initialize() { + addTypes(); + addAttributes< +#define GET_ATTRDEF_LIST +#include "aie/AIEAttrs.cpp.inc" + >(); + addOperations< +#define GET_OP_LIST +#include "aie/AIEOps.cpp.inc" + >(); + addInterfaces(); +} + +} // namespace xilinx::AIE + +// Check that the operation only contains terminators in +// TerminatorOpTypes. +template +struct HasSomeTerminator { + static LogicalResult verifyTrait(Operation *op) { + for (auto ®ion : op->getRegions()) { + for (auto &block : region) { + if (!block.empty()) { + if (Operation *operation = &block.back(); + !llvm::isa_and_nonnull(operation)) + return operation->emitOpError("is not an allowed terminator") + .attachNote(op->getLoc()) + .append("in this context: "); + } + } + } + return success(); + } +}; + +// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) +// has valid BDs. +template +LogicalResult HasValidBDs::verifyTrait(Operation *op) { + auto element = cast(op); + const auto &targetModel = getTargetModel(op); + int bdMax = + targetModel.getNumBDs(element.getTileID().col, element.getTileID().row); + + int bdNum = 0; + for (auto &block : element.getBody()) { + if (!block.template getOps().empty()) { + if (bdNum >= bdMax) { + auto bd = *block.template getOps().begin(); + return (op->emitOpError("has more than ") << bdMax << " blocks") + .attachNote(bd.getLoc()) + .append("no space for this bd: "); + } + bdNum++; + } + } + return success(); +} + +// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) +// has valid DMA channels. +template +LogicalResult HasValidDMAChannels::verifyTrait(Operation *op) { + auto element = cast(op); + DenseSet usedChannels; + for (auto &bodyOp : element.getBody().getOps()) { + // check for duplicate DMA channels within the same MemTileDMAOp + if (auto dmaStart = dyn_cast(bodyOp)) { + DMAChannel dmaChan = {dmaStart.getChannelDir(), + dmaStart.getChannelIndex()}; + if (usedChannels.count(dmaChan)) + return dmaStart.emitOpError() + << "duplicate DMA channel " + << stringifyDMAChannelDir(dmaChan.direction) << dmaChan.channel + << " not allowed"; + usedChannels.insert(dmaChan); + } + } + return success(); +} + +//===----------------------------------------------------------------------===// +// ObjectFifoCreateOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoCreateOp::verify() { + if (isa(getElemNumber())) { + if (size_t numDepths = dyn_cast(getElemNumber()).size(); + numDepths != getConsumerTiles().size() + 1) // +1 for producer depth + return emitOpError("does not have enough depths specified for producer " + "and for each consumer."); + } + + if (getProducerTileOp().isShimTile() && !getDimensionsToStream().empty()) { + return emitError("`toStream` data layout transformations are not supported " + "on shim tile producers"); + } + + return success(); +} + +TileOp ObjectFifoCreateOp::getProducerTileOp() { + return cast(getProducerTile().getDefiningOp()); +} + +namespace xilinx::AIE { + +ParseResult parseObjectFifoProducerTile(OpAsmParser &parser, + OpAsmParser::UnresolvedOperand &operand, + BDDimLayoutArrayAttr &dimensions) { + std::vector emptyDims = {}; + if (parser.parseOperand(operand)) + return failure(); + if (succeeded(parser.parseOptionalKeyword("toStream"))) { + if (parser.parseCustomAttributeWithFallback( + dimensions)) { + return failure(); + } + } else { + dimensions = + BDDimLayoutArrayAttr::get(parser.getContext(), ArrayRef(emptyDims)); + } + return success(); +} + +void printObjectFifoProducerTile(OpAsmPrinter &printer, Operation *op, + Value operand, + BDDimLayoutArrayAttr dimensions) { + printer << operand; + if (!dimensions.empty()) { + printer << " toStream "; + printer.printStrippedAttrOrType(dimensions); + } +} + +ParseResult parseObjectFifoConsumerTiles( + OpAsmParser &parser, SmallVectorImpl &tiles, + BDDimLayoutArrayArrayAttr &dimensions) { + // parseCommaSeparatedList doesn't handle the missing case for "none", + // so we handle it custom here. + std::vector tileDims = {}; + + auto parseOneOperand = [&]() -> ParseResult { + if (parser.parseOperand(tiles.emplace_back(), true)) { + return failure(); + } + // 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 + BDDimLayoutArrayAttr dimAttr = + BDDimLayoutArrayAttr::get(parser.getContext(), {}); + + if (succeeded(parser.parseOptionalKeyword("fromStream"))) { + // If specified, parse actual data layout transform dimensions + if (parser.parseCustomAttributeWithFallback( + dimAttr)) { + return failure(); + } + } + tileDims.emplace_back(dimAttr); + return success(); + }; + + if (parser.parseCommaSeparatedList(AsmParser::Delimiter::None, + parseOneOperand, " in operand list")) + return failure(); + + dimensions = BDDimLayoutArrayArrayAttr::get(parser.getContext(), tileDims); + return success(); +} + +void printObjectFifoConsumerTiles(OpAsmPrinter &printer, Operation *op, + OperandRange tiles, + BDDimLayoutArrayArrayAttr dimsPerTileAttr) { + size_t tileIdx = 0; + for (auto tile : tiles) { + printer << tile; + if (dimsPerTileAttr && tileIdx < dimsPerTileAttr.size() && + dimsPerTileAttr[tileIdx] && !dimsPerTileAttr[tileIdx].empty()) { + printer << " fromStream "; + printer.printStrippedAttrOrType(dimsPerTileAttr[tileIdx]); + } + if (tileIdx < tiles.size() - 1) { + printer << ", "; + } + tileIdx++; + } +} + +} // namespace xilinx::AIE + +//===----------------------------------------------------------------------===// +// ObjectFifoLinkOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoLinkOp::verify() { + if (isJoin() && isDistribute()) + return emitError("ObjectFifoLinkOp does not support 'join' and " + "'distribute' at the same time"); + + if (auto sharedTile = getOptionalSharedTile(); !sharedTile) + return emitError("ObjectFifoLinkOp must have a link point, i.e., a " + "shared tile between objectFifos"); + + if (isJoin()) { + ObjectFifoCreateOp fifoOut = getOutputObjectFifos()[0]; + auto elemType = + llvm::cast(fifoOut.getElemType()).getElementType(); + int64_t outputSize = 1; + for (auto dim : elemType.getShape()) + outputSize *= dim; + + int inputSize = 0; + for (auto fifoIn : getInputObjectFifos()) { + auto elemType = + llvm::cast(fifoIn.getElemType()).getElementType(); + int64_t nextInputSize = 1; + for (int64_t dim : elemType.getShape()) + nextInputSize *= dim; + inputSize += nextInputSize; + } + if (inputSize != outputSize) + return emitError("Total size of input objFifos in ObjectFifoLinkOp must " + "be equal to size of output objFifo"); + + } else if (isDistribute()) { + ObjectFifoCreateOp fifoIn = getInputObjectFifos()[0]; + if (!fifoIn.getDimensionsToStream().empty()) { + return emitOpError("currently does not support objectFifos with " + "dimensionsToStream."); + } + for (auto dims : fifoIn.getDimensionsFromStreamPerConsumer()) { + if (!dims.empty()) + return emitOpError("currently does not support objectFifos with " + "dimensionsFromStreamPerConsumer."); + } + + auto elemType = + llvm::cast(fifoIn.getElemType()).getElementType(); + int64_t inputSize = 1; + for (auto dim : elemType.getShape()) + inputSize *= dim; + + int outputSize = 0; + for (auto fifoOut : getOutputObjectFifos()) { + for (auto dims : fifoOut.getDimensionsFromStreamPerConsumer()) { + if (!dims.empty()) + return emitOpError("currently does not support objectFifos with " + "dimensionsFromStreamPerConsumer."); + } + + auto elemType = + llvm::cast(fifoOut.getElemType()).getElementType(); + int64_t nextOutputSize = 1; + for (int64_t dim : elemType.getShape()) + nextOutputSize *= dim; + outputSize += nextOutputSize; + } + if (outputSize != inputSize) + return emitError("Total size of output objFifos in ObjectFifoLinkOp must " + "be equal to size of input objFifo"); + } + + return success(); +} + +std::optional ObjectFifoLinkOp::getOptionalSharedTile() { + if (isJoin()) { + auto fifoOut = getOutputObjectFifos()[0]; + for (auto fifoIn : getInputObjectFifos()) + if (fifoOut.getProducerTile() != fifoIn.getConsumerTiles()[0]) + return {}; + return {fifoOut.getProducerTile()}; + } + + if (isDistribute()) { + auto fifoIn = getInputObjectFifos()[0]; + for (auto fifoOut : getOutputObjectFifos()) + if (fifoIn.getConsumerTiles()[0] != fifoOut.getProducerTile()) + return {}; + return {fifoIn.getConsumerTiles()[0]}; + } + + auto fifoIn = getInputObjectFifos(); + if (auto fifoOut = getOutputObjectFifos(); + !fifoIn.empty() && !fifoOut.empty()) + for (auto consumerIn : fifoIn[0].getConsumerTiles()) + if (consumerIn == fifoOut[0].getProducerTile()) + return {fifoOut[0].getProducerTile()}; + return {}; +} + +std::vector ObjectFifoLinkOp::getInputObjectFifos() { + std::vector inputObjFifos; + Operation *parent = getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + for (auto sym : getFifoIns()) { + auto name = dyn_cast(sym); + if (auto *st = SymbolTable::lookupSymbolIn(parent, name); + isa_and_nonnull(st)) + inputObjFifos.push_back(dyn_cast(st)); + } + } + } + return inputObjFifos; +} + +std::vector ObjectFifoLinkOp::getOutputObjectFifos() { + std::vector outputObjFifos; + Operation *parent = getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + for (auto sym : getFifoOuts()) { + auto name = dyn_cast(sym); + if (auto *st = SymbolTable::lookupSymbolIn(parent, name); + isa_and_nonnull(st)) + outputObjFifos.push_back(dyn_cast(st)); + } + } + } + return outputObjFifos; +} + +//===----------------------------------------------------------------------===// +// ObjectFifoRegisterExternalBuffersOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoRegisterExternalBuffersOp::verify() { + if (!getTileOp().isShimTile()) + return emitOpError("tile is not a shim tile"); + + return success(); +} + +TileOp ObjectFifoRegisterExternalBuffersOp::getTileOp() { + return cast(getTile().getDefiningOp()); +} + +ObjectFifoCreateOp ObjectFifoRegisterExternalBuffersOp::getObjectFifo() { + Operation *parent = getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); + isa_and_nonnull(st)) + return dyn_cast(st); + } + } + return {}; +} + +//===----------------------------------------------------------------------===// +// ObjectFifoAcquireOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoAcquireOp::verify() { + if (acqNumber() < 1) + return emitOpError("must acquire at least one element"); + + auto parent = getOperation()->getParentOfType(); + if (parent == nullptr) + return emitOpError("must be called from inside a CoreOp"); + + auto coreTile = parent.getTile(); + auto objFifo = getObjectFifo(); + if (getPort() == ObjectFifoPort::Produce) { + if (coreTile != objFifo.getProducerTile()) + return parent.emitOpError( + "producer port of objectFifo accessed by core running " + "on non-producer tile"); + } else if (getPort() == ObjectFifoPort::Consume) { + bool found = false; + for (auto consumerTile : objFifo.getConsumerTiles()) { + if (coreTile == consumerTile) { + found = true; + break; + } + } + if (!found) + return parent.emitOpError( + "consumer port of objectFifo accessed by core running " + "on non-consumer tile"); + } + + auto objFifoElem = + llvm::cast(getObjectFifo().getElemType()) + .getElementType(); + auto objFifoSubviewElem = + llvm::cast(getResult().getType()) + .getElementType(); + if (objFifoElem != objFifoSubviewElem) + return emitOpError( + "ObjectFifo element and ObjectFifoSubview element must match.\n"); + + return success(); +} + +ObjectFifoCreateOp ObjectFifoAcquireOp::getObjectFifo() { + Operation *parent = getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); + isa_and_nonnull(st)) + return dyn_cast(st); + } + } + return {}; +} + +//===----------------------------------------------------------------------===// +// ObjectFifoReleaseOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoReleaseOp::verify() { + if (relNumber() < 1) + return emitOpError("must release at least one element"); + + auto parent = getOperation()->getParentOfType(); + if (parent == nullptr) + return emitOpError("must be called from inside a CoreOp"); + + auto coreTile = parent.getTile(); + auto objFifo = getObjectFifo(); + if (getPort() == ObjectFifoPort::Produce) { + if (coreTile != objFifo.getProducerTile()) + return parent.emitOpError( + "producer port of objectFifo accessed by core running " + "on non-producer tile"); + } else if (getPort() == ObjectFifoPort::Consume) { + bool found = false; + for (auto consumerTile : objFifo.getConsumerTiles()) { + if (coreTile == consumerTile) { + found = true; + break; + } + } + if (!found) + return parent.emitOpError( + "consumer port of objectFifo accessed by core running " + "on non-consumer tile"); + } + + return success(); +} + +ObjectFifoCreateOp ObjectFifoReleaseOp::getObjectFifo() { + Operation *parent = getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); + isa_and_nonnull(st)) + return dyn_cast(st); + } + } + return {}; +} + +//===----------------------------------------------------------------------===// +// ObjectFifoSubviewAccessOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoSubviewAccessOp::verify() { + if (auto parent = getOperation()->getParentOfType(); + parent == nullptr) + return emitOpError("must be called from inside a CoreOp"); + + if (auto acqOp = getSubview().getDefiningOp(); + getIndex() >= acqOp.acqNumber()) + return emitOpError("accessed farther than number of acquired elements " + "(index out of bounds)."); + + return success(); +} + +//===----------------------------------------------------------------------===// +// ObjectFifoRegisterProcessOp +//===----------------------------------------------------------------------===// + +LogicalResult ObjectFifoRegisterProcessOp::verify() { + if (getProcessLength() < 1) + return emitOpError("process length must be >= 1"); + + if (getAcquirePattern().size() != getReleasePattern().size()) { + // acquire pattern size = process length (i.e., release pattern will be + // duplicated by process length times) OR the other way around + if (getAcquirePattern().size() != getProcessLength() && + getProcessLength() != getReleasePattern().size()) + return emitOpError( + "Acquire and Release patterns must be of equal length, or " + "longest length of one must be equal to process " + "length of the other"); + } + + return success(); +} + +ObjectFifoCreateOp ObjectFifoRegisterProcessOp::getObjectFifo() { + Operation *parent = getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); + isa_and_nonnull(st)) + return dyn_cast(st); + } + } + return {}; +} + +//===----------------------------------------------------------------------===// +// CascadeFlowOp +//===----------------------------------------------------------------------===// + +LogicalResult CascadeFlowOp::verify() { + TileOp src = getSourceTileOp(); + TileOp dst = getDestTileOp(); + const auto &t = getTargetModel(src); + + if (src.isShimTile() || dst.isShimTile()) + return emitOpError("shimTile row has no cascade stream interface"); + if (t.isMemTile(src.colIndex(), src.rowIndex()) || + t.isMemTile(dst.colIndex(), dst.rowIndex())) + return emitOpError("memTile row has no cascade stream interface"); + + if (!t.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow()) && + !t.isWest(src.getCol(), src.getRow(), dst.getCol(), dst.getRow()) && + !t.isNorth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow()) && + !t.isEast(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + return emitOpError("tiles must be adjacent"); + } + return success(); +} + +TileOp CascadeFlowOp::getSourceTileOp() { + return cast(getSourceTile().getDefiningOp()); +} + +TileOp CascadeFlowOp::getDestTileOp() { + return cast(getDestTile().getDefiningOp()); +} + +//===----------------------------------------------------------------------===// +// ConfigureCascadeOp +//===----------------------------------------------------------------------===// + +LogicalResult ConfigureCascadeOp::verify() { + const auto &t = getTargetModel(*this); + TileOp tile = cast(getTile().getDefiningOp()); + CascadeDir inputDir = getInputDir(); + CascadeDir outputDir = getOutputDir(); + + if (tile.isShimTile()) + return emitOpError("shimTile row has no cascade stream interface"); + if (t.isMemTile(tile.colIndex(), tile.rowIndex())) + return emitOpError("memTile row has no cascade stream interface"); + + if (t.getTargetArch() == AIEArch::AIE2) { + if (inputDir == CascadeDir::South || inputDir == CascadeDir::East) { + return emitOpError("input direction of cascade must be North or West on ") + << stringifyAIEArch(t.getTargetArch()); + } + if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { + return emitOpError( + "output direction of cascade must be South or East on ") + << stringifyAIEArch(t.getTargetArch()); + } + } else { + return emitOpError("cascade not supported in ") + << stringifyAIEArch(t.getTargetArch()); + } + return success(); +} + +//===----------------------------------------------------------------------===// +// PutCascadeOp +//===----------------------------------------------------------------------===// + +LogicalResult PutCascadeOp::verify() { + const auto &targetModel = getTargetModel(*this); + Type type = getCascadeValue().getType(); + DataLayout dataLayout = DataLayout::closest(*this); + auto bits = dataLayout.getTypeSizeInBits(type); + auto archbits = targetModel.getAccumulatorCascadeSize(); + if (bits != archbits) + return emitOpError("type must match architecture cascade width (") + << archbits << " bits in " + << stringifyAIEArch(targetModel.getTargetArch()) << ")"; + return success(); +} + +//===----------------------------------------------------------------------===// +// GetCascadeOp +//===----------------------------------------------------------------------===// + +LogicalResult GetCascadeOp::verify() { + const auto &targetModel = getTargetModel(*this); + Type type = getCascadeValue().getType(); + DataLayout dataLayout = DataLayout::closest(*this); + auto bits = dataLayout.getTypeSizeInBits(type); + if (targetModel.getTargetArch() == AIEArch::AIE1) { + if (bits != 384) + return emitOpError("must be a 384-bit type"); + } else if (targetModel.getTargetArch() == AIEArch::AIE2) { + if (bits != 512) + return emitOpError("must be a 512-bit type"); + } else + return emitOpError("cascade not supported in ") + << stringifyAIEArch(targetModel.getTargetArch()); + return success(); +} + +//===----------------------------------------------------------------------===// +// DeviceOp +//===----------------------------------------------------------------------===// + +const AIETargetModel &DeviceOp::getTargetModel() { + return xilinx::AIE::getTargetModel(getDevice()); +} + +LogicalResult DeviceOp::verify() { return success(); } + +//===----------------------------------------------------------------------===// +// TileOp +//===----------------------------------------------------------------------===// + +LogicalResult TileOp::verify() { + const auto &targetModel = getTargetModel(*this); + int columns = targetModel.columns(); + int rows = targetModel.rows(); + if (colIndex() >= columns) + return emitOpError("column index (") + << colIndex() + << ") must be less than the number of columns in the device (" + << columns << ")"; + if (rowIndex() >= rows) + return emitOpError("row index (") + << rowIndex() + << ") must be less than the number of rows in the device (" << rows + << ")"; + + auto users = getResult().getUsers(); + bool found = false; + for (auto *user : users) { + if (llvm::isa(*user)) { + if (found) + return emitOpError("can only have one switchbox"); + found = true; + } + } + + return success(); +} + +size_t TileOp::getNumSourceConnections(WireBundle bundle) { + const auto &targetModel = getTargetModel(*this); + if (bundle == WireBundle::Core || bundle == WireBundle::DMA) + // Note dest is correct here, since direction is reversed. + { + // Note dest is correct here, since direction is reversed. + if (targetModel.isShimNOCTile(getCol(), getRow()) || + targetModel.isShimPLTile(getCol(), getRow())) + return targetModel.getNumDestShimMuxConnections(getCol(), getRow(), + bundle); + return targetModel.getNumDestSwitchboxConnections(getCol(), getRow(), + bundle); + } + return 0; +} + +size_t TileOp::getNumDestConnections(WireBundle bundle) { + const auto &targetModel = getTargetModel(*this); + if (bundle == WireBundle::Core || bundle == WireBundle::DMA) + // Note source is correct here, since direction is reversed. + { + // Note source is correct here, since direction is reversed. + if (targetModel.isShimNOCTile(getCol(), getRow()) || + targetModel.isShimPLTile(getCol(), getRow())) + return targetModel.getNumDestShimMuxConnections(getCol(), getRow(), + bundle); + return targetModel.getNumSourceSwitchboxConnections(getCol(), getRow(), + bundle); + } + return 0; +} + +bool TileOp::isMemTile() { + const auto &targetModel = getTargetModel(*this); + return targetModel.isMemTile(getCol(), getRow()); +} + +bool TileOp::isShimNOCTile() { + const auto &targetModel = getTargetModel(*this); + return targetModel.isShimNOCTile(getCol(), getRow()); +} + +bool TileOp::isShimPLTile() { + const auto &targetModel = getTargetModel(*this); + return targetModel.isShimPLTile(getCol(), getRow()); +} + +bool TileOp::isShimNOCorPLTile() { + const auto &targetModel = getTargetModel(*this); + return targetModel.isShimNOCorPLTile(getCol(), getRow()); +} + +bool isLegalTileConnection(TileOp tile, const AIETargetModel &targetModel, + MasterSetOp masterOp, PacketRulesOp slaveOp) { + auto srcBundle = slaveOp.sourcePort().bundle; + auto srcChan = slaveOp.sourcePort().channel; + auto dstBundle = masterOp.destPort().bundle; + auto dstChan = masterOp.destPort().channel; + return targetModel.isLegalTileConnection( + tile.colIndex(), tile.rowIndex(), srcBundle, srcChan, dstBundle, dstChan); +} + +bool isLegalTileConnection(TileOp tile, const AIETargetModel &targetModel, + ConnectOp connectOp) { + auto srcBundle = connectOp.getSourceBundle(); + auto srcChan = connectOp.getSourceChannel(); + auto dstBundle = connectOp.getDestBundle(); + auto dstChan = connectOp.getDestChannel(); + return targetModel.isLegalTileConnection( + tile.colIndex(), tile.rowIndex(), srcBundle, srcChan, dstBundle, dstChan); +} + +//===----------------------------------------------------------------------===// +// ShimSwitchboxOp +//===----------------------------------------------------------------------===// + +LogicalResult ShimSwitchboxOp::verify() { + Region &body = getConnections(); + DenseSet destset; + if (body.empty()) + return emitOpError("should have non-empty body"); + + for (auto &ops : body.front()) { + if (auto connectOp = dyn_cast(ops)) { + Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; + if (destset.count(dest)) + return connectOp.emitOpError("targets same destination ") + << stringifyWireBundle(dest.bundle) << ": " << dest.channel + << " as another connect operation"; + destset.insert(dest); + } else if (isa(ops)) { + // continue; + } else { + return ops.emitOpError("cannot be contained in a Switchbox op"); + } + } + + return success(); +} + +//===----------------------------------------------------------------------===// +// ShimMuxOp +//===----------------------------------------------------------------------===// + +LogicalResult ShimMuxOp::verify() { + Region &body = getConnections(); + DenseSet destset; + if (body.empty()) + return emitOpError("should have non-empty body"); + + for (auto &ops : body.front()) { + if (auto connectOp = dyn_cast(ops)) { + Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; + if (destset.count(dest)) + return connectOp.emitOpError("targets same destination ") + << stringifyWireBundle(dest.bundle) << ": " << dest.channel + << " as another connect operation"; + destset.insert(dest); + } else if (isa(ops)) { + // continue; + } else { + return ops.emitOpError("cannot be contained in a Switchbox op"); + } + } + return success(); +} + +size_t ShimMuxOp::getNumSourceConnections(WireBundle bundle) { + auto tile = getTileOp(); + const auto &targetModel = getTargetModel(*this); + return targetModel.getNumSourceShimMuxConnections(tile.getCol(), + tile.getRow(), bundle); +} + +size_t ShimMuxOp::getNumDestConnections(WireBundle bundle) { + auto tile = getTileOp(); + const auto &targetModel = getTargetModel(*this); + return targetModel.getNumDestShimMuxConnections(tile.getCol(), tile.getRow(), + bundle); +} + +TileOp ShimMuxOp::getTileOp() { + return cast(getTile().getDefiningOp()); +} + +int ShimMuxOp::colIndex() { return getTileOp().colIndex(); } + +int ShimMuxOp::rowIndex() { return getTileOp().rowIndex(); } + +//===----------------------------------------------------------------------===// +// ShimDMAOp +//===----------------------------------------------------------------------===// + +LogicalResult ShimDMAOp::verify() { + Region &body = getBody(); + DenseSet usedChannels; + std::vector inputChannels; + std::vector outputChannels; + + if (getBody().empty()) + return emitOpError("should have non-empty body"); + + if (!getTileOp().isShimNOCTile()) + return emitOpError("must be in a ShimTile with a NOC connection"); + + if (HasSomeTerminator::verifyTrait(*this) + .failed()) + return failure(); + + for (auto &bodyOp : body.getOps()) { + // check for duplicate DMA channels within the same ShimDMAOp + if (auto dmaStart = dyn_cast(bodyOp)) { + DMAChannel dmaChan = {dmaStart.getChannelDir(), + dmaStart.getChannelIndex()}; + if (usedChannels.count(dmaChan)) + return dmaStart.emitOpError() + << "duplicate DMA channel " + << stringifyDMAChannelDir(dmaChan.direction) << dmaChan.channel + << " in MemOp"; + usedChannels.insert(dmaChan); + // check if number of input and output channels is more than available + // hardware + if (dmaChan.direction == DMAChannelDir::S2MM) + inputChannels.push_back(dmaChan); + else + outputChannels.push_back(dmaChan); + } + } + + if (inputChannels.size() > + getTileOp().getNumSourceConnections(WireBundle::DMA)) + return emitOpError("uses more input channels than available on this tile"); + + if (outputChannels.size() > + getTileOp().getNumDestConnections(WireBundle::DMA)) + return emitOpError("uses more output channels than available on this tile"); + + return success(); +} + +TileOp ShimDMAOp::getTileOp() { + return cast(getTile().getDefiningOp()); +} + +int ShimDMAOp::colIndex() { return getTileOp().colIndex(); } + +int ShimDMAOp::rowIndex() { return getTileOp().rowIndex(); } + +LogicalResult PacketRulesOp::verify() { + if (Region &body = getRules(); body.empty()) + return emitOpError("should have non-empty body"); + return success(); +} + +LogicalResult PacketFlowOp::verify() { + Region &body = getPorts(); + if (body.empty()) + return emitOpError("should have non-empty body"); + + for (auto &ops : body.front()) { + if (!isa(ops)) + return ops.emitOpError("cannot be contained in a PacketFlow op"); + } + + return success(); +} + +//===----------------------------------------------------------------------===// +// CoreOp +//===----------------------------------------------------------------------===// + +LogicalResult CoreOp::verify() { + if (getBody().empty()) + return emitOpError("should have non-empty body"); + if (getTileOp().isShimTile()) + return emitOpError("CoreOp cannot be created on shim tile, i.e. row == 0"); + if (getTileOp().isMemTile()) + return emitOpError("CoreOp cannot be created on mem tile"); + return success(); +} + +int CoreOp::colIndex() { return getTileOp().colIndex(); } + +int CoreOp::rowIndex() { return getTileOp().rowIndex(); } + +TileOp CoreOp::getTileOp() { return cast(getTile().getDefiningOp()); } + +//===----------------------------------------------------------------------===// +// BufferOp +//===----------------------------------------------------------------------===// + +int64_t BufferOp::getAllocationSize() { + auto type = llvm::cast(getType()); + return type.getNumElements() * type.getElementTypeBitWidth() / 8; +} + +TileOp BufferOp::getTileOp() { return cast(getTile().getDefiningOp()); } + +LogicalResult BufferOp::verify() { + if (UsesAreAccessable::verifyTrait(*this).failed()) + return failure(); + return success(); +} + +// FIXME: make address assignment for buffers explicit and move this function to +// an interface +int32_t xilinx::AIE::getBufferBaseAddress(Operation *bufOp) { + if (auto buf = dyn_cast(bufOp)) { + assert(buf.getAddress().has_value() && "buffer must have address assigned"); + return buf.getAddress().value(); + } + if (isa_and_nonnull(bufOp)) + llvm::report_fatal_error( + "External buffer addresses are assigned at runtime."); + llvm::report_fatal_error("unknown buffer type"); +} + +void xilinx::AIE::collectTiles(DeviceOp &device, + DenseMap &tiles) { + for (auto tile : device.getOps()) { + int colIndex = tile.colIndex(); + int rowIndex = tile.rowIndex(); + tiles[{colIndex, rowIndex}] = tile; + } +} + +void xilinx::AIE::collectBuffers( + DeviceOp &device, + DenseMap> &buffers) { + for (BufferOp buffer : device.getOps()) { + Operation *tileOp = buffer.getTile().getDefiningOp(); + buffers[tileOp].push_back(buffer); + } +} + +static void printBufferInitialValue(OpAsmPrinter &p, BufferOp op, Type type, + Attribute initialValue) { + if (op.getInitialValue()) { + p << "= "; + p.printAttributeWithoutType(initialValue); + } +} + +static ParseResult parseBufferInitialValue(OpAsmParser &parser, Type &type, + Attribute &initialValue) { + auto memrefType = llvm::cast(type); + if (!memrefType.hasStaticShape()) + return parser.emitError(parser.getNameLoc()) + << "type should be static shaped memref, but got " << type; + + if (parser.parseOptionalEqual()) + return success(); + + Type tensorType = mlir::memref::getTensorTypeFromMemRefType(memrefType); + if (parser.parseAttribute(initialValue, tensorType)) + return failure(); + if (!llvm::isa(initialValue)) + return parser.emitError(parser.getNameLoc()) + << "initial value should be an elements attribute"; + return success(); +} + +//===----------------------------------------------------------------------===// +// MemOp +//===----------------------------------------------------------------------===// + +LogicalResult MemOp::verify() { + Region &body = getBody(); + DenseSet usedChannels; + std::vector inputChannels; + std::vector outputChannels; + if (body.empty()) + return emitOpError("should have non-empty body"); + + if (HasSomeTerminator::verifyTrait(*this) + .failed()) + return failure(); + + for (auto &bodyOp : body.getOps()) { + // check for duplicate DMA channels within the same MemOp + if (auto dmaStart = dyn_cast(bodyOp)) { + DMAChannel dmaChan = {dmaStart.getChannelDir(), + dmaStart.getChannelIndex()}; + if (usedChannels.count(dmaChan)) + return dmaStart.emitOpError() + << "duplicate DMA channel " + << stringifyDMAChannelDir(dmaChan.direction) << dmaChan.channel + << " in MemOp"; + usedChannels.insert(dmaChan); + // check if number of input and output channels is more than available + // hardware + if (dmaChan.direction == DMAChannelDir::S2MM) + inputChannels.push_back(dmaChan); + else + outputChannels.push_back(dmaChan); + } + + if (auto allocOp = dyn_cast(bodyOp)) + if (!allocOp->getAttr("id")) + return allocOp.emitOpError() + << "allocOp in MemOp region should have an id attribute"; + } + + if (inputChannels.size() > + getTileOp().getNumSourceConnections(WireBundle::DMA)) + return emitOpError("uses more input channels than available on this tile"); + + if (outputChannels.size() > + getTileOp().getNumDestConnections(WireBundle::DMA)) + return emitOpError("uses more output channels than available on this tile"); + + return success(); +} + +TileOp MemOp::getTileOp() { return cast(getTile().getDefiningOp()); } + +int MemOp::colIndex() { return getTileOp().colIndex(); } + +int MemOp::rowIndex() { return getTileOp().rowIndex(); } + +/// Returns the region on the current operation that is callable. This may +/// return nullptr in the case of an external callable object, e.g. an external +/// function. +Region *MemOp::getCallableRegion() { return &getBody(); } + +//===----------------------------------------------------------------------===// +// MemTileDMAOp +//===----------------------------------------------------------------------===// + +LogicalResult MemTileDMAOp::verify() { + std::vector inputChannels; + std::vector outputChannels; + + assert(getOperation()->getNumRegions() == 1 && + "MemTileDMAOp has zero region!"); + assert(!getBody().empty() && "MemTileDMAOp should have non-empty body"); + + if (HasSomeTerminator::verifyTrait(*this) + .failed()) + return failure(); + + for (auto &bodyOp : getBody().getOps()) { + if (auto allocOp = dyn_cast(bodyOp)) { + if (!allocOp->getAttr("id")) + return allocOp.emitOpError() + << "allocOp in MemTileDMAOp region should have an id attribute"; + } + if (auto startOp = dyn_cast(bodyOp)) { + // check if number of input and output channels is more than available + // hardware + DMAChannel dmaChan = {startOp.getChannelDir(), startOp.getChannelIndex()}; + if (dmaChan.direction == DMAChannelDir::S2MM) + inputChannels.push_back(dmaChan); + else + outputChannels.push_back(dmaChan); + + if (startOp.getChannelIndex() > 3) { + // Channels 4 and 5 in a memtile are restricted to only access local + // buffers and locks. + + // TODO: Move this code to the dialect + // Set of blocks found to be reachable within a given region. + llvm::SmallSet reachable; + SmallVector worklist; + Block *firstBD = startOp.getSuccessor(0); + reachable.insert(firstBD); + worklist.push_back(firstBD); + while (!worklist.empty()) { + Block *block = worklist.pop_back_val(); + if (block->empty()) + continue; + auto successors = block->getTerminator()->getSuccessors(); + for (auto *i : successors) { + if (!reachable.contains(i)) { + reachable.insert(i); + worklist.push_back(i); + } + } + } + for (Block *b : reachable) { + for (DMABDOp bd : b->getOps()) { + if (auto bufferOp = bd.getBufferOp(); + bufferOp.getTileOp().colIndex() != colIndex() || + bufferOp.getTileOp().rowIndex() != rowIndex()) { + InFlightDiagnostic err = + bd.emitOpError() + << "is reachable from DMA channel " + << startOp.getChannelIndex() + << " and attempts to access a non-local buffer\n"; + err.attachNote(startOp->getLoc()) << "channel"; + err.attachNote(bufferOp->getLoc()) << "buffer"; + return err; + } + } + for (auto useLock : b->getOps()) { + if (auto lockOp = useLock.getLockOp(); + lockOp.getTileOp().colIndex() != colIndex() || + lockOp.getTileOp().rowIndex() != rowIndex()) { + InFlightDiagnostic err = + useLock.emitOpError() + << "is reachable from DMA channel " + << startOp.getChannelIndex() + << " and attempts to access a non-local lock\n"; + err.attachNote(startOp->getLoc()) << "channel"; + err.attachNote(lockOp->getLoc()) << "lock"; + return err; + } + } + } + } + } + } + + if (inputChannels.size() > + getTileOp().getNumSourceConnections(WireBundle::DMA)) + return emitOpError("uses more input channels than available on this tile"); + + if (outputChannels.size() > + getTileOp().getNumDestConnections(WireBundle::DMA)) + return emitOpError("uses more output channels than available on this tile"); + + return success(); +} + +//===----------------------------------------------------------------------===// +// DMAOp +//===----------------------------------------------------------------------===// + +LogicalResult DMAOp::verify() { + auto *parentOp = getOperation()->getParentOp(); + if (parentOp->getRegion(0).getBlocks().size() > 1) + return emitOpError("DMAOp can only appear in single block region"); + if (!parentOp->getRegion(0).getOps().empty()) + return emitOpError("DMAOp is not compatible with DMAStart ops"); + auto bdRegions = getBds(); + for (auto &bdRegion : bdRegions) { + if (!bdRegion.hasOneBlock()) + return emitOpError("DMAOp regions must have only one block"); + auto bds = llvm::to_vector_of(bdRegion.front().getOps()); + if (bds.size() != 1) + return emitOpError("DMAOp regions/blocks must have exactly one DMABDOp"); + auto useLocks = + llvm::to_vector_of(bdRegion.front().getOps()); + if (useLocks.size() != 2) + return emitOpError( + "DMAOp regions/blocks must have exactly two UseLock ops"); + } + return success(); +} + +//===----------------------------------------------------------------------===// +// DMABDOp +//===----------------------------------------------------------------------===// + +BufferOp DMABDOp::getBufferOp() { + return cast(getBuffer().getDefiningOp()); +} + +LogicalResult DMABDOp::verify() { + if (!isa(getBuffer().getDefiningOp())) + return emitOpError( + "BDs only support BufferOp or ExternalBufferOp operands."); + + if (getLenInBytes() % 4) + return emitOpError("transfer length must be multiple of 4 (i.e., represent " + "4 byte aligned address)"); + + TileID parentTileId = getParentTileElement(getOperation()).getTileID(); + + if (getOperation()->getParentOfType() && + (getBufferOp().getTileOp().colIndex() != parentTileId.col || + getBufferOp().getTileOp().rowIndex() != parentTileId.row)) + return emitOpError( + "Core tile DMAs can only access a buffer in the same tile."); + + const AIETargetModel &targetModel = getTargetModel(getOperation()); + + uint32_t maxBds = targetModel.getNumBDs(parentTileId.col, parentTileId.row); + if (std::optional bdId = getBdId(); + bdId.has_value() && static_cast(*bdId) >= maxBds) + return emitOpError("bdId attribute exceeds max: ") << maxBds - 1; + if (std::optional nextBdId = getNextBdId(); + nextBdId.has_value() && static_cast(*nextBdId) >= maxBds) + return emitOpError("nextBdId attribute exceeds max: ") << maxBds - 1; + if (auto dims = getDimensions(); dims.has_value()) { + size_t maxNDims = 3; + if (isa_and_nonnull(getOperation()->getParentOp())) + maxNDims = 4; + if (dims->size() > maxNDims) + return emitOpError() << "Cannot give more than " + << std::to_string(maxNDims) + << " dimensions for step sizes and wraps in this " + " tile (got " + << std::to_string(dims->size()) << " dimensions)."; + + MemRefType buffer = getBuffer().getType(); + int64_t maxIdx = 0; + for (BDDimLayoutAttr dim : *dims) { + maxIdx += dim.getStride() * (dim.getSize() - 1); + if (0 == dim.getStride()) + return emitOpError() + << "Invalid step size; must be a positive integer."; + if (dim.getStride() > buffer.getNumElements()) + return emitOpError() + << "Step size " << std::to_string(dim.getStride()) << " " + << "exceeds memref size " + << std::to_string(buffer.getNumElements()); + if (dim.getSize() >= (1UL << 9) + 1) + return emitOpError() << "Size may not exceed 1023."; + if (dim.getStride() >= (1UL << 19)) + return emitOpError() << "Stride may not exceed " << (1 << 20); + } + + if (buffer.getNumElements() <= maxIdx) + return emitOpError() << "Specified stride(s) and size(s) result in out " + "of bounds access in buffer, for index " + << std::to_string(maxIdx) << " in memref of length " + << std::to_string(buffer.getNumElements()) << "."; + + // Since streams read 32b words, there's no way to read eg 16b with stride + // of 2 (ie lower halfs of each 32b). So force it to be 1 (and then in + // CDODirect/XAIEV2 scale the size by 4/getBufferElementTypeWidthInBytes). + if (getBufferElementTypeWidthInBytes() < 4 && dims->back().getStride() != 1) + return emitOpError( + "For <32b width datatypes, inner-most dim stride must be 1"); + } + if (auto paddims = getPadDimensions(); paddims.has_value()) { + auto dims = getDimensions(); + if (!dims.has_value()) + return emitOpError() << "Padding requires n-d data layouts expressed as" + << " wrap(s) and stride(s)."; + if (dims->size() != paddims->size()) + return emitOpError() << "Mismatch number of dimensions between padding(s)" + << " and wrap(s) and stride(s)."; + if (!targetModel.isMemTile(parentTileId.col, parentTileId.row)) + return emitOpError() << "Padding is only supported by memtile dma bds."; + int actuallen = 1; + for (unsigned i = 0; i < paddims->size(); i++) { + auto dim = (*dims)[i]; + auto paddim = (*paddims)[i]; + actuallen *= paddim.getConstPadBefore() + paddim.getConstPadAfter() + + dim.getSize(); + if (actuallen > getLen()) + return emitOpError() << "Data exceeds len after padding."; + } + if ((paddims->back().getConstPadBefore() * + getBufferElementTypeWidthInBytes()) % + 4) + return emitOpError() << "Inner-most padding-before count must result in" + << " padding in 32-bit words."; + if ((paddims->back().getConstPadAfter() * + getBufferElementTypeWidthInBytes()) % + 4) + return emitOpError() << "Inner-most padding-after count must result in" + << " padding in 32-bit words."; + } + if (targetModel.isMemTile(parentTileId.col, parentTileId.row) || + targetModel.isCoreTile(parentTileId.col, parentTileId.row)) { + if (auto baseAddr = getBufferOp().getAddress(); baseAddr.has_value()) { + int offsetInBytes = *baseAddr + getOffsetInBytes(); + if (offsetInBytes % 4) + return emitOpError( + "bd address must be 4 byte (32b) aligned; got base+offset: ") + << offsetInBytes << " (bytes)"; + } + } + + if (!getLen() && !getBuffer().getType().hasStaticShape()) + return emitOpError() << "buffer with dynamic shape requires static length."; + + return success(); +} + +TileOp MemTileDMAOp::getTileOp() { + return cast(getTile().getDefiningOp()); +} + +int MemTileDMAOp::colIndex() { return getTileOp().colIndex(); } + +int MemTileDMAOp::rowIndex() { return getTileOp().rowIndex(); } + +/// Returns the region on the current operation that is callable. This may +/// return nullptr in the case of an external callable object, e.g. an external +/// function. +Region *MemTileDMAOp::getCallableRegion() { return &getBody(); } + +//===----------------------------------------------------------------------===// +// SwitchboxOp +//===----------------------------------------------------------------------===// + +LogicalResult SwitchboxOp::verify() { + Region &body = getConnections(); + DenseSet sourceset; + DenseSet destset; + auto tile = getTileOp(); + const auto &targetModel = getTargetModel(tile); + if (body.empty()) + return emitOpError("should have non-empty body"); + for (auto &ops : body.front()) { + // Would be simpler if this could be templatized. + auto checkBound = [&ops](StringRef dir, WireBundle bundle, int index, + int bound) -> LogicalResult { + if (index >= bound) { + if (bound > 0) + return ops.emitOpError("index ") + << index << " for " << dir << " bundle " + << stringifyWireBundle(bundle) << " must be less than " + << bound; + return ops.emitOpError() + << dir << " bundle " << stringifyWireBundle(bundle) + << " not supported; index: " << index << ", bound: " << bound; + } + return success(); + }; + + if (auto connectOp = dyn_cast(ops)) { + Port source = {connectOp.getSourceBundle(), connectOp.sourceIndex()}; + sourceset.insert(source); + + Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; + if (destset.count(dest)) { + return connectOp.emitOpError() + << "; connecting " << to_string(source) << " to " + << to_string(dest) << " on " + << to_string(this->getTileOp().getTileID()) + << " targets same dst as another connect op; existing " + "destinations: " + << llvm::join(llvm::map_range( + destset, [](auto &p) { return to_string(p); }), + ", "); + } + destset.insert(dest); + + if (connectOp.sourceIndex() < 0) + return connectOp.emitOpError("source index cannot be less than zero"); + + if (checkBound("source", connectOp.getSourceBundle(), + connectOp.sourceIndex(), + getNumSourceConnections(connectOp.getSourceBundle())) + .failed()) + return failure(); + + if (connectOp.destIndex() < 0) + return connectOp.emitOpError("dest index cannot be less than zero"); + + if (checkBound("dest", connectOp.getDestBundle(), connectOp.destIndex(), + getNumDestConnections(connectOp.getDestBundle())) + .failed()) + return failure(); + + // Stream switch connection constraints + if (!isLegalTileConnection(tile, targetModel, connectOp)) + return connectOp.emitOpError("illegal stream switch connection"); + + } else if (auto connectOp = dyn_cast(ops)) { + Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; + if (destset.count(dest)) + return connectOp.emitOpError("targets same destination ") + << stringifyWireBundle(dest.bundle) << ": " << dest.channel + << " as another connect or masterset operation"; + destset.insert(dest); + + if (connectOp.destIndex() < 0) + return connectOp.emitOpError("dest index cannot be less than zero"); + + if (checkBound("dest", connectOp.getDestBundle(), connectOp.destIndex(), + getNumDestConnections(connectOp.getDestBundle())) + .failed()) + return failure(); + + int arbiter = -1; + for (auto val : connectOp.getAmsels()) { + auto amsel = dyn_cast(val.getDefiningOp()); + if (arbiter != -1 && arbiter != amsel.arbiterIndex()) + return connectOp.emitOpError( + "a master port can only be tied to one arbiter"); + arbiter = amsel.arbiterIndex(); + } + } else if (auto connectOp = dyn_cast(ops)) { + Port source = {connectOp.getSourceBundle(), connectOp.sourceIndex()}; + if (sourceset.count(source)) + return connectOp.emitOpError("packet switched source ") + << stringifyWireBundle(source.bundle) << source.channel + << " cannot match another connect or masterset operation"; + sourceset.insert(source); + + } else if (auto amselOp = dyn_cast(ops)) { + std::vector mstrs; + std::vector slvs; + for (auto *user : amselOp.getResult().getUsers()) { + if (auto s = dyn_cast(user)) { + auto pktRules = dyn_cast(s->getParentOp()); + slvs.push_back(pktRules); + } else if (auto m = dyn_cast(user)) + mstrs.push_back(m); + } + for (auto m : mstrs) { + for (auto s : slvs) { + // Stream switch connection constraints + if (!isLegalTileConnection(tile, targetModel, m, s)) { + return amselOp->emitOpError("illegal stream switch connection"); + } + } + } + } else if (isa(ops)) { + // continue; + } else { + return ops.emitOpError("cannot be contained in a Switchbox op"); + } + } + + return success(); +} + +TileOp SwitchboxOp::getTileOp() { + return cast(getTile().getDefiningOp()); +} + +int SwitchboxOp::colIndex() { return getTileOp().colIndex(); } + +int SwitchboxOp::rowIndex() { return getTileOp().rowIndex(); } + +template +struct HasSomeParent { + static LogicalResult verifyTrait(Operation *op) { + Operation *operation = op->getParentOp(); + while (operation) { + if (llvm::isa_and_nonnull(operation)) + return success(); + operation = operation->getParentOp(); + } + return failure(); + } +}; + +TileOp LockOp::getTileOp() { return cast(getTile().getDefiningOp()); } + +int LockOp::colIndex() { return getTileOp().colIndex(); } + +int LockOp::rowIndex() { return getTileOp().rowIndex(); } + +LogicalResult LockOp::verify() { + if (auto result = UsesAreAccessable::verifyTrait(*this); result.failed()) + return result; + + if (getLockID().has_value()) { + const auto &targetModel = getTargetModel(getTileOp()); + auto tileOp = getTileOp(); + if (int numLocks = + targetModel.getNumLocks(tileOp.getCol(), tileOp.getRow()); + getLockID().value() >= numLocks) + return emitOpError("lock assigned invalid id (maximum is ") + << numLocks - 1 << ")"; + } + + return success(); +} + +struct UsesOneLockInDMABlock { + static LogicalResult verifyTrait(Operation *op) { + auto *block = op->getBlock(); + int lockID = -1; + for (auto op : block->getOps()) { + if (auto lock = dyn_cast(op.getLock().getDefiningOp()); + lock.getLockID().has_value()) { + if (lockID != -1 && lockID != lock.getLockIDValue()) + return failure(); + lockID = lock.getLockIDValue(); + } + } + return success(); + } +}; + +struct AcquireReleaseOneStateInDMABlock { + static LogicalResult verifyTrait(Operation *op) { + auto *block = op->getBlock(); + int acqValue = -1, relValue = -1; + for (auto op : block->getOps()) { + if (op.acquire() || op.acquireGE()) { + if (acqValue != -1 && acqValue != op.getLockValue()) { + return failure(); + } + acqValue = op.getLockValue(); + } else if (op.release()) { + if (relValue != -1 && relValue != op.getLockValue()) { + return failure(); + } + relValue = op.getLockValue(); + } + } + return success(); + } +}; + +struct AccessesLocalLocks { + static LogicalResult verifyTrait(Operation *op) { + if (auto memOp = op->getParentOfType()) { + auto useLock = dyn_cast(op); + if (auto lock = useLock.getLockOp(); + lock.getTileOp().colIndex() != memOp.colIndex() || + lock.getTileOp().rowIndex() != memOp.rowIndex()) + return failure(); + } + return success(); + } +}; + +LogicalResult UseLockOp::verify() { + // AIE.useLock cannot be used at the top level + if (llvm::isa_and_nonnull((*this)->getParentOp())) + return (*this)->emitOpError("must be used in a core or memory operation."); + + const auto &targetModel = getTargetModel(*this); + if (targetModel.getTargetArch() == AIEArch::AIE1 && acquireGE()) + return (*this)->emitOpError( + "AcquireGreaterEqual is not supported in AIE1."); + + // Otherwise, AIE.useLock should be inside MemOp, MemTileDMAOp, or ShimDMAOp, + if (HasSomeParent::verifyTrait(*this) + .succeeded()) { + if (!(*this)->getBlock()) + return (*this)->emitOpError("is not in a block."); + + if (targetModel.getTargetArch() == AIEArch::AIE1 && + UsesOneLockInDMABlock::verifyTrait(*this).failed()) + return (*this)->emitOpError( + "used in a DMA block that have multiple locks."); + + if (AcquireReleaseOneStateInDMABlock::verifyTrait(*this).failed()) + return (*this)->emitOpError( + "acquires/releases the lock in a DMA block from/to multiple states."); + + if (HasSomeParent::verifyTrait(*this).succeeded() && + AccessesLocalLocks::verifyTrait(*this).failed()) + return (*this)->emitOpError("can only access a lock in the same tile"); + return success(); + + // Or it can be in a CoreOp, or some FuncOp called from a CoreOp + } + if (HasSomeParent::verifyTrait(*this).succeeded()) { + return success(); + } + return (*this)->emitOpError() + << "expects some parent op to be one of " + << "AIE::device, AIE::core, func::func, AIE::mem, or AIE::shimDMA"; +} + +#include "aie/AIEEnums.cpp.inc" +#include "aie/AIEInterfaces.cpp.inc" + +#define GET_OP_CLASSES +#include "aie/AIEOps.cpp.inc" + +namespace xilinx::AIE { + +size_t SwitchboxOp::getNumSourceConnections(WireBundle bundle) { + auto tile = getTileOp(); + const auto &targetModel = getTargetModel(*this); + return targetModel.getNumSourceSwitchboxConnections(tile.getCol(), + tile.getRow(), bundle); +} + +size_t SwitchboxOp::getNumDestConnections(WireBundle bundle) { + auto tile = getTileOp(); + const auto &targetModel = getTargetModel(*this); + return targetModel.getNumDestSwitchboxConnections(tile.getCol(), + tile.getRow(), bundle); +} + +WireBundle getConnectingBundle(WireBundle dir) { + switch (dir) { + case WireBundle::North: + return WireBundle::South; + case WireBundle::South: + return WireBundle::North; + case WireBundle::East: + return WireBundle::West; + case WireBundle::West: + return WireBundle::East; + default: + return dir; + } +} + +} // namespace xilinx::AIE + +// Include implementations for custom attributes +#define GET_ATTRDEF_CLASSES +#include "aie/AIEAttrs.cpp.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h new file mode 100644 index 000000000..2f7d8d8b5 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -0,0 +1,391 @@ +//===- AIEDialect.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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_AIE_DIALECT_H +#define MLIR_AIE_DIALECT_H + +#include "AIEEnums.h" + +#include "AIETargetModel.h" + +#include "mlir/Dialect/Arith/IR/Arith.h" +#include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" +#include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/Dialect/LLVMIR/LLVMDialect.h" +#include "mlir/Dialect/MemRef/IR/MemRef.h" +#include "mlir/Dialect/SCF/IR/SCF.h" +#include "mlir/IR/BuiltinAttributes.h" +#include "mlir/IR/Dialect.h" +#include "mlir/IR/OpDefinition.h" +#include "mlir/IR/OpImplementation.h" +#include "mlir/IR/Types.h" + +namespace xilinx::AIE { + +// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) +// has valid BDs. +template +struct HasValidBDs : mlir::OpTrait::TraitBase { + static mlir::LogicalResult verifyTrait(mlir::Operation *op); +}; + +// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) +// has valid channels. +template +struct HasValidDMAChannels + : mlir::OpTrait::TraitBase { + static mlir::LogicalResult verifyTrait(mlir::Operation *op); +}; + +class TileOp; +} // namespace xilinx::AIE + +namespace xilinx::AIE { +mlir::LogicalResult +verifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op); +} // namespace xilinx::AIE + +/// Include the generated interface declarations. +#include "aie/AIEInterfaces.h.inc" + +namespace xilinx::AIE { +mlir::LogicalResult +myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op); +template +struct MyOffsetSizeAndStrideOpInterfaceTrait + : public ::mlir::detail::OffsetSizeAndStrideOpInterfaceTrait { + static ::mlir::LogicalResult verifyTrait(::mlir::Operation *op) { + return myVerifyOffsetSizeAndStrideOp( + ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(op)); + } +}; + +struct MyOffsetSizeAndStrideOpInterface + : ::mlir::OffsetSizeAndStrideOpInterface { + template + struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait {}; +}; +} // namespace xilinx::AIE + +// Include dialect declarations such as parseAttributes, parseType +#include "aie/AIEDialect.h.inc" + +namespace xilinx::AIE { + +void registerAIETranslations(); + +} // namespace xilinx::AIE + +//////////////////////////////////////////////////////////////////////////////// +/////////////////////// Custom Types for the Dialect /////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace xilinx::AIE { +namespace detail { +struct AIEObjectFifoTypeStorage; +} + +/// This class defines the AIE ObjectFifo type. +class AIEObjectFifoType + : public mlir::Type::TypeBase { +public: + /// Inherit some necessary constructors from 'TypeBase'. + using Base::Base; + + /// Create an instance of a `ObjectFifoType` with the given element type. + static AIEObjectFifoType get(mlir::MemRefType elementType); + + /// This method is used to verify the construction invariants. + static mlir::LogicalResult + verify(llvm::function_ref emitError, + mlir::MemRefType elementType); + + static constexpr llvm::StringLiteral name = "objectfifo"; + /// Returns the element type of this ObjectFifoType. + mlir::MemRefType getElementType(); +}; + +namespace detail { +struct AIEObjectFifoSubviewTypeStorage; +} + +/// This class defines the AIE ObjectFifoSubview type. +class AIEObjectFifoSubviewType + : public mlir::Type::TypeBase { +public: + /// Inherit some necessary constructors from 'TypeBase'. + using Base::Base; + + /// Create an instance of a `SubviewType` with the given element type. + static AIEObjectFifoSubviewType get(mlir::MemRefType elementType); + + /// This method is used to verify the construction invariants. + static mlir::LogicalResult + verify(llvm::function_ref emitError, + mlir::MemRefType elementType); + + static constexpr llvm::StringLiteral name = "objectfifosubview"; + /// Returns the element type of this SubviewType. + mlir::MemRefType getElementType(); +}; + +} // namespace xilinx::AIE + +//////////////////////////////////////////////////////////////////////////////// +// Custom Attributes /////////////////////////////////////////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +#define GET_ATTRDEF_CLASSES +#include "aie/AIEAttrs.h.inc" + +//////////////////////////////////////////////////////////////////////////////// +//////////////////// Custom Operations for the Dialect ///////////////////////// +//////////////////////////////////////////////////////////////////////////////// + +namespace xilinx::AIE { + +WireBundle getConnectingBundle(WireBundle dir); + +#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP) \ + friend std::string to_string(const TYPE_WITH_INSERTION_OP &s) { \ + std::ostringstream ss; \ + ss << s; \ + return ss.str(); \ + } + +typedef struct Port { + WireBundle bundle; + int channel; + + bool operator==(const Port &rhs) const { + return std::tie(bundle, channel) == std::tie(rhs.bundle, rhs.channel); + } + + bool operator!=(const Port &rhs) const { return !(*this == rhs); } + + bool operator<(const Port &rhs) const { + return std::tie(bundle, channel) < std::tie(rhs.bundle, rhs.channel); + } + + friend std::ostream &operator<<(std::ostream &os, const Port &port) { + os << "("; + switch (port.bundle) { + case WireBundle::Core: + os << "Core"; + break; + case WireBundle::DMA: + os << "DMA"; + break; + case WireBundle::North: + os << "N"; + break; + case WireBundle::East: + os << "E"; + break; + case WireBundle::South: + os << "S"; + break; + case WireBundle::West: + os << "W"; + break; + default: + os << "X"; + break; + } + os << ": " << std::to_string(port.channel) << ")"; + return os; + } + + GENERATE_TO_STRING(Port) + + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, + const Port &port) { + os << to_string(port); + return os; + } + +} Port; + +typedef struct Connect { + Port src; + Port dst; + + bool operator==(const Connect &rhs) const { + return std::tie(src, dst) == std::tie(rhs.src, rhs.dst); + } +} Connect; + +typedef struct DMAChannel { + DMAChannelDir direction; + int channel; + + bool operator==(const DMAChannel &rhs) const { + return std::tie(direction, channel) == std::tie(rhs.direction, rhs.channel); + } +} DMAChannel; + +const AIETargetModel &getTargetModel(mlir::Operation *op); +const AIETargetModel &getTargetModel(AIEDevice device); + +mlir::ParseResult +parseObjectFifoProducerTile(mlir::OpAsmParser &parser, + mlir::OpAsmParser::UnresolvedOperand &operand, + BDDimLayoutArrayAttr &dimensions); + +void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::Value tile, + mlir::Attribute dimensions); + +mlir::ParseResult parseObjectFifoConsumerTiles( + mlir::OpAsmParser &parser, + llvm::SmallVector &tiles, + BDDimLayoutArrayArrayAttr &dimensions); + +void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::OperandRange tiles, + mlir::Attribute dimensions); + +int32_t getBufferBaseAddress(mlir::Operation *bufOp); + +} // namespace xilinx::AIE + +// include TableGen generated Op definitions +#define GET_OP_CLASSES +#include "aie/AIEOps.h.inc" + +namespace xilinx::AIE { + +void collectTiles(DeviceOp &device, + llvm::DenseMap &tiles); + +void collectBuffers( + DeviceOp &device, + llvm::DenseMap> &buffers); +} // namespace xilinx::AIE + +namespace llvm { +// Functions hash just like pointers. +template <> +struct DenseMapInfo { + static xilinx::AIE::ObjectFifoAcquireOp getEmptyKey() { + auto *pointer = DenseMapInfo::getEmptyKey(); + return xilinx::AIE::ObjectFifoAcquireOp::getFromOpaquePointer(pointer); + } + + static xilinx::AIE::ObjectFifoAcquireOp getTombstoneKey() { + auto *pointer = DenseMapInfo::getTombstoneKey(); + return xilinx::AIE::ObjectFifoAcquireOp::getFromOpaquePointer(pointer); + } + + static unsigned getHashValue(xilinx::AIE::ObjectFifoAcquireOp val) { + return hash_value(val.getAsOpaquePointer()); + } + + static bool isEqual(xilinx::AIE::ObjectFifoAcquireOp lhs, + xilinx::AIE::ObjectFifoAcquireOp rhs) { + return lhs == rhs; + } +}; +} // namespace llvm + +namespace llvm { +// Functions hash just like pointers. +template <> +struct DenseMapInfo { + static xilinx::AIE::ObjectFifoCreateOp getEmptyKey() { + auto *pointer = DenseMapInfo::getEmptyKey(); + return xilinx::AIE::ObjectFifoCreateOp::getFromOpaquePointer(pointer); + } + + static xilinx::AIE::ObjectFifoCreateOp getTombstoneKey() { + auto *pointer = DenseMapInfo::getTombstoneKey(); + return xilinx::AIE::ObjectFifoCreateOp::getFromOpaquePointer(pointer); + } + + static unsigned getHashValue(xilinx::AIE::ObjectFifoCreateOp val) { + return hash_value(val.getAsOpaquePointer()); + } + + static bool isEqual(xilinx::AIE::ObjectFifoCreateOp lhs, + xilinx::AIE::ObjectFifoCreateOp rhs) { + return lhs == rhs; + } +}; + +template <> +struct DenseMapInfo { + using FirstInfo = DenseMapInfo; + using SecondInfo = DenseMapInfo; + + static xilinx::AIE::DMAChannel getEmptyKey() { + return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; + } + + static xilinx::AIE::DMAChannel getTombstoneKey() { + return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; + } + + static unsigned getHashValue(const xilinx::AIE::DMAChannel &d) { + return detail::combineHashValue(FirstInfo::getHashValue(d.direction), + SecondInfo::getHashValue(d.channel)); + } + + static bool isEqual(const xilinx::AIE::DMAChannel &lhs, + const xilinx::AIE::DMAChannel &rhs) { + return lhs == rhs; + } +}; + +template <> +struct DenseMapInfo { + using FirstInfo = DenseMapInfo; + using SecondInfo = DenseMapInfo; + + static xilinx::AIE::Port getEmptyKey() { + return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; + } + + static xilinx::AIE::Port getTombstoneKey() { + return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; + } + + static unsigned getHashValue(const xilinx::AIE::Port &d) { + return detail::combineHashValue(FirstInfo::getHashValue(d.bundle), + SecondInfo::getHashValue(d.channel)); + } + + static bool isEqual(const xilinx::AIE::Port &lhs, + const xilinx::AIE::Port &rhs) { + return lhs == rhs; + } +}; + +} // namespace llvm + +template <> +struct std::less { + bool operator()(const xilinx::AIE::Port &a, + const xilinx::AIE::Port &b) const { + return a.bundle == b.bundle ? a.channel < b.channel : a.bundle < b.bundle; + } +}; + +template <> +struct std::hash { + std::size_t operator()(const xilinx::AIE::Port &p) const noexcept { + std::size_t h1 = std::hash{}(p.bundle); + std::size_t h2 = std::hash{}(p.channel); + return h1 ^ h2 << 1; + } +}; + +#endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h b/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h new file mode 100644 index 000000000..caa255f83 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h @@ -0,0 +1,19 @@ +//===- AIEEnums.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 2023 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_AIE_ENUMS_H +#define MLIR_AIE_ENUMS_H + +#include "mlir/IR/BuiltinTypes.h" +#include "mlir/IR/Dialect.h" + +#include "aie/AIEEnums.h.inc" + +#endif \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td new file mode 100644 index 000000000..5bf2dcdd1 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td @@ -0,0 +1,139 @@ +//===- AIEInterfaces.td ------------------------------------*- tablegen -*-===// +// +// 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 2020 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + + +#ifndef AIE_INTERFACES +#define AIE_INTERFACES + +include "AIE.td" + +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"> { + string cppNamespace = "::xilinx::AIE"; +} + +// Op is a DMA-like operation with valid channels +def HasValidDMAChannels : NativeOpTrait<"HasValidDMAChannels"> { + string cppNamespace = "::xilinx::AIE"; +} + +def PredIsCoreTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isCoreTile(llvm::cast($_op).getTileID().col," + "llvm::cast($_op).getTileID().row)">; +def PredIsMemTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isMemTile(llvm::cast($_op).getTileID().col," + "llvm::cast($_op).getTileID().row)">; +def PredIsShimNOCTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isShimNOCTile(llvm::cast($_op).getTileID().col," + "llvm::cast($_op).getTileID().row)">; +def PredIsShimPLTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isShimPLTile(llvm::cast($_op).getTileID().col," + "llvm::cast($_op).getTileID().row)">; + +def IsCoreTile : PredOpTrait<"op exists in a core tile", PredIsCoreTile>; +def IsMemTile : PredOpTrait<"op exists in a MemTile", PredIsMemTile>; +def IsTileWithMemory : PredOpTrait<"op exists in a tile with local memory", Or<[PredIsCoreTile, PredIsMemTile]>>; +def IsShimTile : PredOpTrait<"op exists in a shim tile", Or<[PredIsShimNOCTile, PredIsShimPLTile]>>; +def IsShimNOCTile : PredOpTrait<"op exists in a shim tile with NOC connection", PredIsShimNOCTile>; +def IsShimPLTile : PredOpTrait<"op exists in a shim tile with PL interface", PredIsShimPLTile>; + +def FlowEndPoint : OpInterface<"FlowEndPoint"> { + let description = [{ + Interface for operations that have interconnect-like properties, + enabling them to host flows for routing. + }]; + let cppNamespace = "::xilinx::AIE"; + let methods = [ + InterfaceMethod<[{}], + "int", "colIndex", (ins ) + >, + InterfaceMethod<[{}], + "int", "rowIndex", (ins ) + > + ]; +} + +def Interconnect : OpInterface<"Interconnect"> { + let description = [{ + Interface for operations that have interconnect-like properties, + enabling them to host flows for routing. + }]; + let cppNamespace = "::xilinx::AIE"; + + let methods = [ + InterfaceMethod<[{}], + "mlir::Region &", "getConnections", (ins ) + >, + InterfaceMethod<[{}], + "int", "colIndex", (ins ) + >, + InterfaceMethod<[{}], + "int", "rowIndex", (ins ) + >, + InterfaceMethod<[{}], + "size_t", "getNumSourceConnections", (ins "WireBundle":$bundle) + >, + InterfaceMethod<[{}], + "size_t", "getNumDestConnections", (ins "WireBundle":$bundle) + > + ]; +} + + +def TileElement : OpInterface<"TileElement", [ + DeclareOpInterfaceMethods, + ]> { + let description = [{ + Interface for operations that exist in a TileOp. + }]; + let cppNamespace = "::xilinx::AIE"; + let methods = [ + InterfaceMethod<[{ + Return the location of the Tile where the element is located. + }], + "xilinx::AIE::TileID", "getTileID", (ins ), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ + ConcreteOp op = llvm::cast(this->getOperation()); + return op.getTileOp().getTileID(); + }] + >, + ]; + let extraTraitClassDeclaration = [{ + void getAsmResultNames( + llvm::function_ref setNameFn) { + ConcreteOp op = llvm::cast(this->getOperation()); + std::string nameWithoutDialect = + op.getOperationName().str().substr(op.getOperationName().find('.') + 1); + setNameFn(op.getResult(), nameWithoutDialect + "_" + + std::to_string(getTileID().col) + "_" + + std::to_string(getTileID().row)); + } + }]; +} + +def AIETarget : OpInterface<"AIETarget"> { + let description = [{ + Interface for operations that model an array of AIEngine cores. + }]; + let cppNamespace = "::xilinx::AIE"; + let methods = [ + InterfaceMethod<[{ + Return the target model describing the characteristics of how this operation will be implemented. + }], + "const ::xilinx::AIE::AIETargetModel&", "getTargetModel", (ins ) + > + ]; +} + +// Don't delete - see AIEDialect::myVerifyOffsetSizeAndStrideOp +def MyOffsetSizeAndStrideOpInterface: OpInterfaceTrait<"::xilinx::AIE::MyOffsetSizeAndStrideOpInterface"> {} + +#endif // AIE_INTERFACES \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td b/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td new file mode 100644 index 000000000..378fec3ba --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td @@ -0,0 +1,30 @@ +//===- AIENormalizeAddressSpaces.td ------------------------*- tablegen -*-===// +// +// 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 2021 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIE_NORMALIZE_ADDRESS_SPACES +#define AIE_NORMALIZE_ADDRESS_SPACES + +include "AIE.td" + +include "mlir/Dialect/MemRef/IR/MemRefOps.td" +include "mlir/IR/PatternBase.td" + +def toDefaultAddressSpace : NativeCodeCall<"TypeAttr::get(memRefToDefaultAddressSpace($0.getValue()))">; +def hasNonDefaultAddressSpace : Constraint< + CPred<"llvm::cast($0.getValue()).getMemorySpace() != 0">, + "has non-default address space">; +def : Pat< + /*pattern*/ (MemRef_GlobalOp $sym_name, $sym_visibility, $type, $initial_value, $constant, $attrs), + /*result*/ (MemRef_GlobalOp $sym_name, $sym_visibility, (toDefaultAddressSpace $type), $initial_value, $constant, $attrs), + /*preds*/ [(hasNonDefaultAddressSpace $type)], + /*supplemental_results*/ [], + /*benefitAdded*/ (addBenefit 20)>; + +#endif // AIE_NORMALIZE_ADDRESS_SPACES diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td new file mode 100644 index 000000000..56562078d --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -0,0 +1,1970 @@ +//===- AIE.td ----------------------------------------------*- tablegen -*-===// +// +// 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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIE_OPS +#define AIE_OPS + +include "AIE.td" +include "AIEAttrs.td" +include "AIEInterfaces.td" +include "AIETypes.td" + +include "mlir/IR/CommonAttrConstraints.td" +include "mlir/IR/SymbolInterfaces.td" +include "mlir/Interfaces/CallInterfaces.td" +include "mlir/Interfaces/InferTypeOpInterface.td" +include "mlir/Interfaces/SideEffectInterfaces.td" + +class AIE_Op traits = []> : + Op; + + +def AIE_DeviceOp: AIE_Op<"device", [ + AIETarget, HasParent<"mlir::ModuleOp">, + SymbolTable, SingleBlock, NoTerminator, IsolatedFromAbove + ]> { + let summary = "Define an AIE design targetting a complete device"; + let description = [{ + This operation describes a design that executes on a particular AIEngine device. + It exists at the toplevel of a design; although currently it does not replace the + default toplevel module in MLIR, the intention is that this could be the case + in the future. + + When using this operation, all resources in a physical device are available and + the design does not need to be concerned with other potential users of a physical + device. In addition, within an `aie.device` operation, tile addresses are absolute + coordinates and are not intended to describe a relocatable design. To describe + a portion of a device which may be relocatable, the intention would be to provide another + operation, for instance maybe `aie.segment`. + The design itself is described using a region of code contained by the device + operation. + + Example: + ``` + aie.device(xcvc1902) { + %tile = aie.tile(1, 1) + %CORE = aie.core(%tile) { ... } + } + ``` + }]; + + let arguments = (ins AIEDevice:$device); + let regions = (region AnyRegion:$body_region); + let assemblyFormat = [{ + `(` $device `)` regions attr-dict + }]; + let extraClassDeclaration = [{ + const xilinx::AIE::AIETargetModel &getTargetModel(); + }]; + let hasVerifier = 1; +} + +def AIE_TileOp: AIE_Op<"tile", [ + Pure, + FlowEndPoint, + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods + ]>, Results<(outs Index:$result)> { + let arguments = ( + ins ConfinedAttr]>:$col, + ConfinedAttr]>:$row + ); + + let summary = "Declare an AIE tile"; + let description = [{ + This operation creates an AIE tile in the AIE array. We specify what the column and the row of the tile. + + A tile encompasses core module (CoreOp), memory module (MemOp), stream switch (SwitchboxOp), + memory buffer (BufferOp), and lock (LockOp). + + A tile is a logical abstraction. We use a tile to establish an ownership of a hardware entity + to it. + Note that row 0 of the Tile array is different from other rows, since it models the shim interface between + the AIE array proper and the PL. The South-West/Lower Right most core exists in Tile(0,1) + }]; + + let extraClassDeclaration = [{ + size_t getNumSourceConnections(WireBundle bundle); + size_t getNumDestConnections(WireBundle bundle); + int colIndex() { return getCol(); } + int rowIndex() { return getRow(); } + TileID getTileID() { return {getCol(), getRow()}; } + bool isShimTile() { return getRow() == 0; } + bool isMemTile(); + bool isShimNOCTile(); + bool isShimPLTile(); + bool isShimNOCorPLTile(); + bool isInternalMemWest() { return ((rowIndex() % 2) == 0); }; + + MemOp getMemOp() { + auto users = getResult().getUsers(); + for(auto user : users) + if(auto memOp = llvm::dyn_cast(*user)) + return memOp; + return nullptr; + } + + CoreOp getCoreOp() { + auto users = getResult().getUsers(); + for(auto user : users) + if(auto coreOp = llvm::dyn_cast(*user)) + return coreOp; + return nullptr; + } + }]; + + let assemblyFormat = [{ + `(` $col `,` $row `)` attr-dict + }]; + + let hasVerifier = 1; + + let extraClassDefinition = [{ + void $cppClass::getAsmResultNames( + function_ref 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]> { + let summary = "end op"; + let description = [{ + A generic terminator operation for AIE ops' regions. + }]; + let assemblyFormat = [{ attr-dict }]; +} + +def AIE_SwitchboxOp: AIE_Op<"switchbox", [ + Interconnect, TileElement, + SingleBlockImplicitTerminator<"EndOp">, + DeclareOpInterfaceMethods + ]>, Results<(outs Index:$result)> { + let arguments = (ins Index:$tile); + + let summary = "Declare a switch"; + let description = [{ + This operation represents the switchbox that is part of a tile. A switchbox is configured + by code in its region, representing various connections + + Example: + ``` + %tile = aie.tile(1, 1) + aie.switchbox(%tile) { + aie.connect<"West" : 0, "Core" : 1> + } + ``` + }]; + + let regions = (region AnyRegion:$connections); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + size_t getNumSourceConnections(WireBundle bundle); + size_t getNumDestConnections(WireBundle bundle); + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; +} + +def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ + SingleBlockImplicitTerminator<"EndOp">, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = (ins I32Attr:$col); + let summary = "Declare a switch in the PL shim"; + let description = [{ + + A switch in the Shim. + AXI-Stream Master Ports AXI-Stream Slave Ports + 6 Ports to North (Core Tile) 4 Ports from North (Core Tile) + 4 Ports to West 4 Ports from West + 4 Ports to East 4 Ports from East + 6 Ports to South(DMA, NoC I/F, PL I/F) 8 Ports from South (DMA, NoC I/F, PL I/F) + 2 Ports to FIFOs 2 Ports from FIFOs + 1 Port for control packet for Shim register access + 1 Port for response to access for Shim registers + 1 Port for trace packet from Shim + + }]; + let regions = (region AnyRegion:$connections); + let assemblyFormat = [{ `(` $col `)` regions attr-dict }]; + let hasVerifier = 1; +} + +def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ + Interconnect, TileElement, IsShimTile, + SingleBlockImplicitTerminator<"EndOp">, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = ( + ins Index:$tile + ); + let summary = "Declare a switch in the PL shim"; + let description = [{ + This operation represents the additional interconnect that is part of a shim interface tile. + Like the `aie.switchbox` operation, `aie.shim_mux` is configured + by code in its region, but can only contain connect operations + + Example: + ``` + %tile = aie.tile(1, 1) + aie.shim_mux(%tile) { + aie.connect<"North" : 0, "DMA" : 1> + } + ``` + }]; + let regions = (region AnyRegion:$connections); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + size_t getNumSourceConnections(WireBundle bundle); + size_t getNumDestConnections(WireBundle bundle); + TileOp getTileOp(); + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; +} + +def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ + FlowEndPoint, TileElement, HasValidBDs, + HasValidDMAChannels, IsShimNOCTile, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = ( + ins Index:$tile + ); + let summary = "Declare a DMA in the PL shim"; + let description = [{ + This operation creates a DMA that belongs to a shim tile. + The region of a ShimDMAOp is used to setup the DMAs and Block Descriptors. + + Example: + ``` + %buf = aie.external_buffer : memref<256xi64> + %lock1 = aie.lock(%t70, 1) + + %dma = aie.shim_dma(%t70) { + aie.dma_start(MM2S, 0, ^bd0, ^end) + ^bd0: + aie.use_lock(%lock1, Acquire, 1) + aie.dma_bd(%buf : memref<512 x i16>, 0, 512) + aie.use_lock(%lock1, Release, 0) + aie.next_bd ^bd0 + ^end: + aie.end + } + ``` + Create the shim_dma for tile `%t70` and setup one DMA channel and one Buffer Descriptor. + }]; + let regions = (region AnyRegion:$body); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; +} + +def AIE_CoreOp: AIE_Op<"core", [ + FlowEndPoint, IsCoreTile, TileElement, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = ( + ins Index:$tile, + DefaultValuedAttr:$stack_size, + OptionalAttr:$link_with, + OptionalAttr:$elf_file + ); + let summary = "Declare a core module"; + let description = [{ + This operation represents an AIEngine processor core belonging to a tile. + The region of a CoreOp contains code that gets run on the AIE core. This code will + typically be outlined into the LLVM dialect, eventually resulting in a binary file + for each core. The name of this file can be be specified using the `elf_file` + attribute. + + This op has an optional `stackSize` attribute, to control the amount of memory (in bytes) + reserved for the stack. The default value is 1024. The stack (and other data allocations) + are always stored in the local core memory, to avoid conflicts with static data allocations + in other cores. + + Examples: + ``` + %tile = aie.tile(1, 1) + %lock11_8 = aie.lock(%tile, 8) + aie.core(%tile) { + aie.use_lock(%lock11_8, "Acquire", 1) + aie.use_lock(%lock11_8, "Release", 0) + aie.end + } + ``` + ``` + %tile = aie.tile(3, 3) + aie.core(%tile) { + aie.end + } { stackSize = 2048 : i32, elf_file = "core_33.elf" } + ``` + }]; + + let regions = (region AnyRegion:$body); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + bool isMemWest() { return ((rowIndex() % 2) == 0); }; + TileOp getTileOp(); + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; + + let builders = [ + OpBuilder<(ins "mlir::Value":$tile), [{ + build($_builder, $_state, $_builder.getIndexType(), tile); + }]> + ]; +} + +def AIE_DebugOp: AIE_Op<"debug", []> { + let arguments = ( + ins AnyType:$arg + ); + let summary = "Capture a value for debugging"; + let description = [{ + Output the given value for debugging. This is primarily used for simulation. + }]; + let assemblyFormat = [{ `(` $arg `:` type($arg) `)` attr-dict }]; +} + +def AIE_PLIOOp: AIE_Op<"plio", [ + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = (ins I32Attr:$col); + let summary = "Declare an interface to the PL"; + let description = [{ + An interface to the PL. + }]; + let assemblyFormat = [{ `(` $col `)` attr-dict }]; + + let extraClassDeclaration = [{ + int colIndex() { return getCol(); } + }]; +} + +def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { + let arguments = ( + ins WireBundle:$source_bundle, + ConfinedAttr]>:$source_channel, + WireBundle:$dest_bundle, + ConfinedAttr]>:$dest_channel + ); + let summary = "A circuit-switched connection inside a switchbox"; + let description = [{ + This operation represents a programmed circuit-switched connection in a stream switch. + It associates a source bundle and source channel with a destination bundle and a destination channel. + This operation must exist within an `aie.switchbox` or `aie.shim_switchbox` operation. + All of the `aie.connect` operations in a switchbox must have a different destinations. + All of the `aie.connect` operations must also have a destination which is different from all + of the `aie.masterset` operations in the same switchbox. + + Example: + ``` + %tile = aie.tile(1, 1) + aie.switchbox(%tile) { + aie.connect<"West" : 0, "Core" : 1> + } + ``` + }]; + + let assemblyFormat = [{ + `<` $source_bundle `:` $source_channel `,` $dest_bundle `:` $dest_channel `>` attr-dict + }]; + + let extraClassDeclaration = [{ + int sourceIndex() { return getSourceChannel(); } + int destIndex() { return getDestChannel(); } + Port sourcePort() { return {getSourceBundle(), sourceIndex()}; } + Port destPort() { return {getDestBundle(), destIndex()}; } + }]; +} + +def AIE_FlowOp: AIE_Op<"flow", []> { + let arguments = ( + ins Index:$source, + WireBundle:$source_bundle, + ConfinedAttr]>:$source_channel, + Index:$dest, + WireBundle:$dest_bundle, + ConfinedAttr]>:$dest_channel + ); + let summary = "A logical circuit-switched connection between cores"; + let description = [{ + The `aie.flow` operation represents a circuit switched connection between two endpoints, usually + `aie.tile` operations. During routing, this is replaced by `aie.connect` operations which represent + the programmed connections inside a switchbox, along with `aie.wire` operations which represent + physical connections between switchboxes and other components. + + Example: + ``` + %00 = aie.tile(0, 0) + %11 = aie.tile(1, 1) + %01 = aie.tile(0, 1) + aie.flow(%00, "DMA" : 0, %11, "Core" : 1) + ``` + }]; + + let assemblyFormat = [{ + `(` $source `,` $source_bundle `:` $source_channel `,` $dest `,` $dest_bundle `:` $dest_channel `)` attr-dict + }]; + + let extraClassDeclaration = [{ + int sourceIndex() { return getSourceChannel(); } + int destIndex() { return getDestChannel(); } + }]; +} + +def AIE_AMSelOp: AIE_Op<"amsel", [ + HasParent<"SwitchboxOp">, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = ( + ins ConfinedAttr, IntMaxValue<5>]>:$arbiterID, + ConfinedAttr, IntMaxValue<3>]>:$msel + ); + let summary = "Declare an arbiter of a switchbox with a master select value (arbiter + msel)"; + let description = [{ + A combination of arbiter ID and master select (msel) value. + This op is used as a pointer to select the arbiter for routing a packet-switched flow + + Example: + ``` + %a0_0 = aie.amsel<5>(3) + %m1 = aie.masterset("East" : 0, %a0_0 ) + aie.packet_rules("South" : 0) { + aie.rule(0x1F, 0x10, %a0_0) + } + ``` + This code associates arbiter 5 with msel=3. A packet-switched connection is made routing + traffic from the South:0 port to the East:0 port using this arbiter. + There are 6 arbiters per switchbox and 4 possible master select values. + See also [MasterSetOp](#aiemasterset-aiemastersetop), + [PacketRulesOp](#aiepacketrules-aiepacketrulesop), and + [PacketRuleOp](#aierule-aiepacketruleop) for more information. + }]; + + let assemblyFormat = [{ + `<` $arbiterID `>` `(` $msel `)` attr-dict + }]; + + let extraClassDeclaration = [{ + int arbiterIndex() { return getArbiterID(); } + int getMselValue() { return getMsel(); } + }]; + + let builders = [ + OpBuilder<(ins "int":$arbiterID, "int":$msel), + [{ + build($_builder, $_state, $_builder.getIndexType(), + $_builder.getI8IntegerAttr(arbiterID), + $_builder.getI8IntegerAttr(msel)); + }]> + ]; +} + +def AIE_MasterSetOp: AIE_Op<"masterset", [ + HasParent<"SwitchboxOp">, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = ( + ins WireBundle:$dest_bundle, + ConfinedAttr]>:$dest_channel, + Variadic:$amsels + ); + let summary = "Packet switched input connection"; + let description = [{ + A Packet switched connection inside a switchbox. + This operation specifies the configuration for a master port. + + Example: + ``` + %a0_m2 = aie.amsel<0>(2) + aie.masterset("Core" : 0, %a0_m2) + ``` + + The code will configure the master port <"Core" : 0> to use arbiter 0 with msel 2 + (see AMSelOp for more details regarding AMSel) + + In the current architecture, a master port can only be associated with one arbiter. However, + a master port can be activated by different msels from one arbiter + + Example: + ``` + %a1_0 = aie.amsel<1>(0) + %a1_1 = aie.amsel<1>(1) + %a2_3 = aie.amsel<2>(3) + + aie.masterset("West" : 2, %a1_0, %a2_3) // this is illegal, please don't do this + aie.masterset("West" : 3, %a1_0, %a1_1) // this is OK + ``` + }]; + + let assemblyFormat = [{ + `(` $dest_bundle `:` $dest_channel `,` $amsels `)` attr-dict + }]; + + let extraClassDeclaration = [{ + int destIndex() { return getDestChannel(); } + Port destPort() { return {getDestBundle(), destIndex()}; } + }]; +} + +def AIE_WireOp: AIE_Op<"wire", []> { + let arguments = ( + ins Index:$source, + WireBundle:$source_bundle, + Index:$dest, + WireBundle:$dest_bundle + ); + let summary = "A bundle of physical wires between components"; + let description = [{ + The `aie.wire` operation represents a physical set of connections between components in a Versal device. + Typically, these components are switches, represented by an `aie.switchbox` operation, and tiles, + represented by an [aie.tile](#aietile-aietileop) operation. + }]; + + let assemblyFormat = [{ + `(` $source `:` $source_bundle `,` $dest `:` $dest_bundle `)` attr-dict + }]; +} + +def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"EndOp">]> { + let arguments = ( + ins WireBundle:$source_bundle, + ConfinedAttr]>:$source_channel + ); + let regions = (region AnyRegion:$rules); + let summary = "Packet switched routing rules"; + let description = [{ + This operation defines packet-switched routing configuration for packets entering a switchbox. + It references a port of the containing swithcbox, which be unique among other packetRules + operations and [aie.connect]($aieconnect-aieconnectop) operations in the containing switchbox. + It contains a region of up to 4 [aie.rule](#aierule-aiepacketruleop) operations. + + See [aie.rule](#aierule-aiepacketruleop) for an example. + }]; + + let assemblyFormat = [{ `(` $source_bundle `:` $source_channel `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int sourceIndex() { return getSourceChannel(); } + Port sourcePort() { return {getSourceBundle(), sourceIndex()}; } + }]; +} + +def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { + let arguments = ( + ins I8Attr:$mask, + I8Attr:$value, + Index:$amsel + ); + let summary = "Packet switched routing rule"; + let description = [{ + This operation defines a matching rule and a destination for packet-switched + connections in a switchbox. Routing is based on the ID field of packet arriving on the + matching port of the containing [aie.packetRules](#aiepacketrules-aiepacketrulesop). + The ID is first bitwise-AND'd with the mask and then checked for equality with the given ID. + It is routed to arbiter and master set associated with the first matching entry. + + Example: + LUT ID | Mask | ID | Arbiter | Msel + --- | --- | --- | --- | --- + 0 | 5'b11111 | 5'b00010 | 4 | 1 + 1 | 5'b11011 | 5'b00001 | 3 | 2 + 2 | | | | + 3 | | | | + + If a packet flow that has an ID of 2, it will be directed to the arbiter 4 with msel 1, + If a packet flow that has an ID of 1 or 5, it will be directed to the arbiter 3 with msel 2, + + We encapsulate the configuration table as follows: + Example: + ``` + %a4_1 = aie.amsel<4>(1) + %a3_2 = aie.amsel<3>(2) + + aie.packet_rules("Core" : 0) { + aie.rule(0x1F, 0x2, %a4_1) + aie.rule(0x1B, 0x1, %a3_2) + } + ``` + }]; + + let extraClassDeclaration = [{ + int maskInt() { return getMask(); } + int valueInt() { return getValue(); } + }]; + + let assemblyFormat = [{ + `(` $mask `,` $value `,` $amsel `)` attr-dict + }]; +} + + +def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndOp">]> { + let summary = "Packet switched flow"; + let description = [{ + A logical packet-switched flow between tiles. During place and + route, this is replaced by MasterSets and PacketRules inside + switchboxes. + + Example: + ``` + %01 = aie.tile(0, 1) + aie.packet_flow(0x10) { + aie.packet_source<%01, "Core" : 0> + aie.packet_dest<%01, "Core" : 0> + } + ``` + }]; + + let arguments = ( + ins I8Attr:$ID, + OptionalAttr:$keep_pkt_header + ); + let regions = (region AnyRegion:$ports); + + let assemblyFormat = [{ `(` $ID `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int IDInt() { return getID(); } + }]; +} + +def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { + let arguments = ( + ins Index:$tile, + WireBundle:$bundle, + ConfinedAttr]>:$channel + ); + let summary = "A sourceport"; + let description = [{ + A object representing the destination of a packet-switched flow. This must exist + within an [aie.packet_flow](#aiepacketflow-aiepacketflowop) operation. + + See [aie.packet_flow](#aiepacketflow-aiepacketflowop) for an example. + }]; + + let assemblyFormat = [{ + `<` $tile `,` $bundle `:` $channel `>` attr-dict + }]; + + let extraClassDeclaration = [{ + int channelIndex() { return getChannel(); } + Port port() { return {getBundle(), channelIndex()}; } + }]; +} + +def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { + let arguments = ( + ins Index:$tile, + WireBundle:$bundle, + ConfinedAttr]>:$channel + ); + let summary = "A destination port"; + let description = [{ + A object representing the destination of a packet-switched flow. This must exist + within an [aie.packet_flow](#aiepacketflow-aiepacketflowop) operation. The destination + Must be unique within a design. + + See [aie.packet_flow](#aiepacketflow-aiepacketflowop) for an example. + }]; + + let assemblyFormat = [{ + `<` $tile `,` $bundle `:` $channel `>` attr-dict + }]; + + let extraClassDeclaration = [{ + int channelIndex() { return getChannel(); } + Port port() { return {getBundle(), channelIndex()}; } + }]; +} + +def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { + let summary = "Enable packet headers for a dma block descriptor"; + 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.dma_bd. + The block descriptor specifies what lock to use and the buffer configuration. + + Example: + ``` + // this defines a BD that uses lock %lck0 and buffer %buf0 + ^bd5: + aie.use_lock(%lck, "Acquire", 0) + aie.dma_bd_packet(0x4, 0xD) + aie.dma_bd(<$buf0 : memref<512xi32>, 0, 512>, 1) + aie.use_lock(%lck, "Release", 1) + br ^bd6 // point to the next Block, which is also a different Block Descriptor + ``` + }]; + + let arguments = ( + ins I32Attr:$packet_type, + I32Attr:$packet_id + ); + + let assemblyFormat = [{ + `(` $packet_type `,` $packet_id `)` attr-dict + }]; + + let extraClassDeclaration = [{ + int getPacketID() { return getPacketId(); } + }]; +} + +def AIE_DMABDOp: AIE_Op<"dma_bd", [ + ParentOneOf<["MemOp", "MemTileDMAOp", "ShimDMAOp", "DMAOp"]>, + ]> { + let summary = "Declare a dma buffer descriptor op"; + let description = [{ + This operation describes a buffer descriptor for DMA operations. In particular, it specifies + what buffer to use, and optionally: + + 1. the offset into the buffer; + 2. the transfer length; + 3. the sizes and strides for n-d tensor addressing (described below); + 4. the "bd_id" with which to associate the buffer descriptor (most often left empty). + 5. the number of zeros to pad before and after every dimension of an n-d tensor (described below); + + `offset`, `len`, `size`s and `stride`s are all denominated in element width; e.g., transferring the whole of + `memref<512xi32>` means `len == 512`, and also while transferring the whole of `memref<512xi16>`, `len == 512`. + + The only caveat to this "everything-is-in-terms-of-element-width" rule is regarding the inner-most dimension's stride + (see [Important gotcha regarding strides](#important-gotcha-regarding-strides) below). + + `dma_bd` ops must appear in their own BBs (basic blocks) and such BBs can (optionally) include `use_lock` + operations (specifying an "acquire" and a "release" lock; see the `use_lock` operation) and subsequent BDs in + a "chain" of BDs (using `next_bd` as a "jump" to the next BB which contains a `dma_bd`). + + Example: + ``` + // this defines a BD that uses lock %lck0 and buffer %buf0 + ^bd5: + aie.use_lock(%lck, "Acquire", 0) + // transfer the first 32 elements of the memref + aie.dma_bd(<$buf0 : memref<128xi32>, 0, 32) + aie.use_lock(%lck, "Release", 1) + aie.next_bd ^bd6 // point to the next bb, which describes the next buffer descriptor + ^bd6: + aie.use_lock(%lck, "Acquire", 1) + // transfer the last 32 elements of the memref + aie.dma_bd(<$buf1 : memref<128xi32>, 96, 32) + aie.use_lock(%lck, "Release", 0) + aie.next_bd ^end + + ... + + // this defines a BD that does not use any lock + ^bd8: + aie.dma_bd(<$buf2 : memref<64xi32>, 0, 64) + ``` + + #### Background/context + + A DMA channel in a Memory Module can process one buffer descriptor after another by chaining them. + There are 16 buffer descriptors per Core memory module and 48 buffer descriptors per Memtile memory module. + They are shared by four DMA channels (or 12). + + #### DMA Data Layout Transformations on AIE-ML Devices + + AIE-ML devices can apply data layout transformations at the buffer + descriptor level. These transformation are described by strides and sizes in up to three dimensions (four + dimensions on memtiles). Strides and sizes can be supplied to the `dma_bd` + through an optional argument, an array of "tuple-like" attributes `bd_dim_layout`. + + The first element of this array gives the outer-most dimension's stride and + size, the last element of the array gives the inner-most dimension's stride and size. + We can model the access pattern strides and sizes generate by a series of + nested loops. In general, a set of strides and sizes like this... + + ``` + [, , ] + ``` + + ...translates to an access pattern that can be epxressed like this: + + ``` + int *buffer; // i32 + for(int i = 0; i < size_2; i++) + for(int j = 0; j < size_1; j++) + for(int k = 0; k < size_0; k++) + // 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: + + ``` + aie.dma_bd(%buf : memref<128xi32>, 0, 128, [<8, 16>, <2, 1>, <8, 2>]) + ``` + + implies + + ``` + for(int i = 0; i < 8 /*size_2*/; i++) + for(int j = 0; j < 2 /*size_1*/; j++) + for(int k = 0; k < 8 /*size_0*/; k++) + // access/store element at/to index (i * 16 /*stride_2*/ + j * 1 /*stride_1*/ + k * 2 /*stride_0*/) + ``` + + #### Important gotcha regarding strides + + All strides are expressed in multiples of the element width (just like `len` and `offset`) + **with the caveat that the inner-most dimension's stride must be 1**. + + ## DMA constant padding on AIE-ML Devices + + AIE-ML devices can apply constant padding at the buffer descriptor level, described with pairs of padding + counts before and after a dimension, to all dimensions in the data layout transformations. The padding + counts can be supplied to the `dma_bd` through an optional argument, an array of "tuple-like" attributes + `bd_pad_layout`, followed by an optional argument `const_val` (default + is 0). All counts are expressed in multiples of the element width. + }]; + + let arguments = ( + ins AnyMemRef:$buffer, + // in multiples of element width (not bytes) + DefaultValuedOptionalAttr:$offset, + // in multiples of element width (not bytes) + OptionalAttr:$len, + OptionalAttr:$dimensions, + OptionalAttr:$pad_dimensions, + DefaultValuedOptionalAttr:$pad_value, + OptionalAttr:$bd_id, + // should never be assigned by user... + OptionalAttr:$next_bd_id + ); + + let hasVerifier = 1; + + let assemblyFormat = [{ + `(` $buffer `:` type($buffer) (`,` $offset^)? (`,` $len^)? (`,` $dimensions^)? (`,` $pad_dimensions^)? (`,` `pad_value` `=` $pad_value^)? `)` attr-dict + }]; + + let extraClassDeclaration = [{ + BufferOp getBufferOp(); + int32_t getBufferElementTypeWidthInBytes() { + return getBuffer().getType().getElementTypeBitWidth() / 8; + } + int32_t getLenInBytes() { + if (std::optional len = getLen(); len.has_value()) + return len.value() * getBufferElementTypeWidthInBytes(); + else + return getBuffer().getType().getNumElements() * getBufferElementTypeWidthInBytes(); + } + int32_t getOffsetInBytes() { return getOffset() * getBufferElementTypeWidthInBytes(); } + }]; + + let hasVerifier = 1; + let builders = [ + OpBuilder<(ins "mlir::Value":$buffer, "int":$offset, "int":$len), [{ + $_state.addOperands(buffer); + $_state.addAttribute("offset", $_builder.getI32IntegerAttr(offset)); + $_state.addAttribute("len", $_builder.getI32IntegerAttr(len)); + }]>, + OpBuilder<(ins "mlir::Value":$buffer, "int":$offset, "int":$len, "BDDimLayoutArrayAttr":$dims), [{ + $_state.addOperands(buffer); + $_state.addAttribute("offset", $_builder.getI32IntegerAttr(offset)); + $_state.addAttribute("len", $_builder.getI32IntegerAttr(len)); + $_state.addAttribute("dimensions", dims); + }]>, + OpBuilder<(ins "mlir::Value":$buffer, "int":$offset, "int":$len, "BDPadLayoutArrayAttr":$paddims), [{ + $_state.addOperands(buffer); + $_state.addAttribute("offset", $_builder.getI32IntegerAttr(offset)); + $_state.addAttribute("len", $_builder.getI32IntegerAttr(len)); + $_state.addAttribute("pad_dimensions", paddims); + }]>, + OpBuilder<(ins "mlir::Value":$buffer, "int":$offset, "int":$len, "BDDimLayoutArrayAttr":$dims, "BDPadLayoutArrayAttr":$paddims), [{ + $_state.addOperands(buffer); + $_state.addAttribute("offset", $_builder.getI32IntegerAttr(offset)); + $_state.addAttribute("len", $_builder.getI32IntegerAttr(len)); + $_state.addAttribute("dimensions", dims); + $_state.addAttribute("pad_dimensions", paddims); + }]> + ]; +} + +def AIE_DMAStartOp: AIE_Op<"dma_start", [ + ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp", "ShimDMAOp"]>, + Terminator, + DeclareOpInterfaceMethods + ]>, Results<(outs I1:$valid)> { + + let summary = "An op to start DMA"; + let description = [{ + This operation declares a DMA channel to be used for data transfer. It usually exists inside + either a MemOp (representing a TileDMA), a MemTileDMAOp (representing a DMA in a MemTile), + or in a ShimDMAOp (representing a ShimDMA). + A channel is defined by a direction (i.e., MM2S or S2MM) and an index. + + Example: + ``` + aie.dma_start("MM2S", 0, ^bd0, ^end) + ^bd0: + aie.use_lock(%lock0, "Acquire", 0) + aie.dma_bd(%buffer : memref<16 x f32>, 0, 16) + aie.use_lock(%lock0, "Release", 1) + br ^bd0 + ^end: + aie.end + ``` + + Conceptually, the aie.dma_start operation is a terminator that either passes + control to a basic block containing DMA operations (through its first successor) + or to a basic block for another dma_start, to an aie.end operation. + }]; + + let arguments = ( + ins DMAChannelDir:$channel_dir, + ConfinedAttr]>:$channel_index, + // repeat_count==0 means "do it once" and don't repeat + DefaultValuedAttr:$repeat_count + ); + let successors = (successor AnySuccessor:$dest, AnySuccessor:$chain); + let assemblyFormat = [{ + `(` $channel_dir `,` $channel_index `,` $dest `,` $chain (`,` `repeat_count` `=` $repeat_count^)? `)` attr-dict + }]; + + let extraClassDeclaration = [{ + bool isSend() { return getChannelDir() == DMAChannelDir::MM2S; } + bool isRecv() { return getChannelDir() == DMAChannelDir::S2MM; } + }]; +} + +def AIE_DMAOp: AIE_Op<"dma", [ + ParentOneOf<["MemOp", "MemTileDMAOp", "ShimDMAOp"]>, + NoTerminator, + DeclareOpInterfaceMethods, + DeclareOpInterfaceMethods + ]>, Results<(outs I1:$valid)> { + + let summary = "An op to describe a set of DMA operations."; + + let arguments = ( + ins DMAChannelDir:$channel_dir, + ConfinedAttr]>:$channel_index, + DefaultValuedAttr:$loop, + // repeat_count==0 means "do it once" and don't repeat + DefaultValuedAttr:$repeat_count, + OptionalAttr:$sym_name + ); + let regions = (region VariadicRegion>:$bds); + let assemblyFormat = [{ + `(` $channel_dir `,` $channel_index `)` + attr-dict ` ` + `[`regions`]` + }]; + let hasVerifier = 1; + + let extraClassDefinition = [{ + void $cppClass::getAsmResultNames( + llvm::function_ref setNameFn) { + if (auto name = getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())) + setNameFn(getResult(), name.str()); + } + }]; +} + + +// 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, + IsCoreTile, HasValidBDs, HasValidDMAChannels, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let summary = "Declare a memory op"; + let description = [{ + This operation creates a Memory module that belongs to a tile. + The region of a MemOp is used to setup the DMAs and Block Descriptors. + See DMAStartOp and DMABdOp for more concrete examples on DMAs and Block Descriptors. + + Example: + ``` + m73 = aie.mem(%t73) { + %srcDma = aie.dma_start("S2MM", 0, ^bd0, ^end) + ^bd0: + aie.use_lock(%lock, "Acquire", 0) + aie.dma_bd(%buf : memref<64xi16>, 0, 64) + aie.use_lock(%lock, "Release", 1) + aie.next_bd ^bd0 + ^end: + aie.end + } + ``` + Create the memory module for tile %t73 and setup one DMA channel and one Buffer Descriptor. + }]; + + let arguments = (ins Index:$tile); + let regions = (region AnyRegion:$body); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + int maxSizeInBytes() { return 32768; } + // CallableOpInterface + mlir::Region *getCallableRegion(); + llvm::ArrayRef getArgumentTypes() { return getOperand().getType(); } + llvm::ArrayRef getResultTypes() { return getType(); } + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; +} + +// This op is not actually Callable, but we want to inline code into them, so we have to +// implement CallableOpInterface +def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ + TileElement, FlowEndPoint, CallableOpInterface, + IsMemTile, HasValidBDs, HasValidDMAChannels, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let summary = "Declare a memtile_dma op"; + let description = [{ + This operation describes a DMA inside an AIE2 MemTile. + The region of the op is used to setup the DMAs and Block Descriptors. + See DMAStartOp and DMABdOp for more concrete examples on DMAs and Block Descriptors. + + This operation is restricted to certain compatible tiles in AIE2 devices: + xcve2302: row 1 + xcve2802: row 1 and 2 + + Example: + ``` + m73 = aie.memtile_dma(%t71) { + %srcDma = aie.dma_start("S2MM", 0, ^bd0, ^end) + ^bd0: + aie.use_lock(%lock, "Acquire", 0) + aie.dma_bd(%buf : memref<64xi16>, 0, 64>, 0) + aie.use_lock(%lock, "Release", 1) + aie.next_bd ^bd0 + ^end: + aie.end + } + ``` + Create a description for tile `%t73` and setup one DMA channel and one Buffer Descriptor. + }]; + + let arguments = (ins Index:$tile); + let regions = (region AnyRegion:$body); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + // CallableOpInterface + mlir::Region *getCallableRegion(); + llvm::ArrayRef getArgumentTypes() { return getOperand().getType(); } + llvm::ArrayRef getResultTypes() { return getType(); } + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; +} + +def AIE_NextBDOp: AIE_Op<"next_bd", [ + Terminator, ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp", "ShimDMAOp"]> + ]> { + let summary = "The next buffer descriptor"; + let description = [{ + This operation terminates the basic block describing a buffer descriptor inside + a tile or shim DMA operation. It references a single following buffer descriptor. + Note that unlike other terminators (like cf.br), canonicalization should not remove + the `next_bd` terminator, since it would result in invalid buffer descriptors. + + Example: + ``` + m73 = aie.mem(%t73) { + %srcDma = aie.dma_start("S2MM", 0, ^bd0, ^end) + ^bd0: + aie.use_lock(%lock, "Acquire", 0) + aie.dma_bd(%buf : memref<64xi16>, 0, 64) + aie.use_lock(%lock, "Release", 1) + aie.next_bd ^bd0 + ^end: + aie.end + } + ``` + }]; + + let successors = (successor AnySuccessor:$dest); + + let assemblyFormat = [{ + $dest attr-dict + }]; +} + +def AIE_LockOp: AIE_Op<"lock", [ + TileElement, Pure, + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let summary = "Declare a physical lock"; + let description = [{ + This operation creates a physical lock. For this operation the lockID variable is optional. + However, if that is the case then the lockID must be assigned using the AIEAssignLockIDs pass. + + Example: + ``` + %tile33 = aie.tile(3, 3) + %lck = aie.lock(%tile33, 7) + ``` + This operation represents a lock that lives in the Memory module of Tile(3, 3) with a lockID of 7 + + Case when LockID is not assigned: + Before AIEAssignLockIDs: `%tile33 = aie.tile(3)` + After AIEAssignLockIDs: `%tile33 = aie.tile(3, $assigned_value)` + }]; + + let arguments = ( + ins Index:$tile, + OptionalAttr]>>:$lockID, + OptionalAttr:$init, + OptionalAttr:$sym_name + ); + + let assemblyFormat = [{ `(` $tile (`,` $lockID^ )? `)` attr-dict }]; + + let extraClassDeclaration = [{ + bool hasName() { + return bool(getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())); + } + + mlir::StringAttr name() { + if (auto attr = getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())) + return attr; + emitOpError("does not have '") + << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; + llvm::report_fatal_error("couldn't get name"); + } + + int getLockIDValue() { + assert(getLockID().has_value() && "Lock has no ID value"); + return getLockID().value(); + } + + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + void getAsmResultNames( + llvm::function_ref setNameFn) { + if (hasName()) + setNameFn(getResult(), name().str()); + else { + std::string nameWithoutDialect = + getOperationName().str().substr(getOperationName().find('.') + 1); + setNameFn(getResult(), nameWithoutDialect + "_" + + std::to_string(getTileID().col) + "_" + + std::to_string(getTileID().row)); + } + } + }]; + + let builders = [ + OpBuilder<(ins "mlir::Value":$tile, "int":$lockID, "int":$init), [{ + build($_builder, $_state, + $_builder.getIndexType(), + tile, + $_builder.getI32IntegerAttr(lockID), + $_builder.getI32IntegerAttr(init), + nullptr + ); + }]> + ]; + let hasVerifier = 1; +} + +def AIE_UseLockOp: AIE_Op<"use_lock", []> { + let summary = "acquire/release lock op"; + let description = [{ + This operation uses a lock. In AIE1, a lock can be acquired with a value, + or released with a value. This should be understood as a "blocking" + operation. In AIE2, locks are counting semaphores without inherent + acquired/release characteristic. This lock must appear in a parent op where + the tile can be determined (A CoreOp, a ShimDMAOp, a MemOp, or a + MemTileDMAOp). + }]; + + let arguments = ( + ins Index:$lock, + LockAction:$action, + OptionalAttr:$value, + OptionalAttr:$blocking, + DefaultValuedOptionalAttr:$acq_en + ); + + let assemblyFormat = [{ + `(` $lock `,` $action (`,` $value^)? (`,` $blocking^)? `)` attr-dict + }]; + + let hasVerifier = 1; + let builders = [ + OpBuilder<(ins "mlir::Value":$lock, + "xilinx::AIE::LockAction":$action, + "int32_t":$value), [{ + build($_builder, $_state, lock, action, $_builder.getI32IntegerAttr(value), nullptr); + }]> + ]; + + let extraClassDeclaration = [{ + bool acquire() { return (getAction() == LockAction::Acquire); } + bool acquireGE() { return (getAction() == LockAction::AcquireGreaterEqual); } + bool release() { return (getAction() == LockAction::Release); } + int getLockValue() { return getValue().value_or(1); } + int getTimeout() { + // LockBlocking is an EnumAttr. + if (auto val = getBlocking()) + return (int)*val; + return 1; + } + LockOp getLockOp() { + return llvm::cast(getLock().getDefiningOp()); + } + }]; +} + +def AIE_BufferOp: AIE_Op<"buffer", [ + TileElement, IsTileWithMemory + ]>, Results<(outs AnyMemRef)> { + let summary = "Declare a buffer"; + let description = [{ + This operation instantiates a buffer that belongs to a Memory Module of a tile. + + Example: + ``` + %tile33 = aie.tile(3, 3) + %buf = aie.buffer(%tile33) : memref<256xi64> + ``` + This operation represents a buffer in tile (3, 3) of 256 elements, each a 64-bit integer. + }]; + + let arguments = ( + ins Index:$tile, + OptionalAttr:$sym_name, + OptionalAttr:$address, + OptionalAttr:$initial_value, + OptionalAttr:$mem_bank + ); + + let results = (outs AnyMemRef:$buffer); + let assemblyFormat = [{ + `(` $tile `)` + attr-dict `:` type($buffer) + custom(ref(type($buffer)), $initial_value) + }]; + let hasVerifier = 1; + + let extraClassDeclaration = [{ + bool hasName() { + return bool(getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())); + } + + mlir::StringAttr name() { + if (auto attr = getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())) + return attr; + emitOpError("does not have '") + << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; + llvm::report_fatal_error("couldn't get name"); + } + + // Return the number of bytes that need to be allocated for this buffer. + int64_t getAllocationSize(); + TileOp getTileOp(); + void getAsmResultNames( + llvm::function_ref setNameFn) { + if (hasName()) + setNameFn(getResult(), name().str()); + else { + std::string nameWithoutDialect = + getOperationName().str().substr(getOperationName().find('.') + 1); + setNameFn(getResult(), nameWithoutDialect + "_" + + std::to_string(getTileID().col) + "_" + + std::to_string(getTileID().row)); + } + } + }]; +} + +def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ + DeclareOpInterfaceMethods + ]>, Results<(outs AnyMemRef)> { + let summary = "Declare a buffer in external memory"; + let description = [{ + This operation represents a buffer that exists in some physical + location in a device, most likely external memory. The exact address + of the external buffer is passed by the mlir_aie_external_set_addr() + and mlir_aie_external_set_addr_myBuffer_ functions in the associated + .cpp test file. + + These external buffers are used within the buffer descriptors of a + shim_dma, i.e., within AIE_DMABdOp operations of a AIE_ShimDMAOp. + + Example: + ``` + %buf = aie.external_buffer : memref<256xi64> + ``` + This operation represents an external buffer. + }]; + + let arguments = (ins OptionalAttr:$sym_name); + + let results = (outs AnyMemRef:$buffer); + let assemblyFormat = [{ attr-dict `:` type($buffer) }]; + + let extraClassDeclaration = [{ + bool hasName() { + return bool(getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())); + } + + mlir::StringAttr name() { + if (auto attr = getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())) + return attr; + emitOpError("does not have '") + << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; + llvm::report_fatal_error("couldn't get name"); + } + }]; + + let extraClassDefinition = [{ + void $cppClass::getAsmResultNames( + llvm::function_ref setNameFn) { + if (hasName()) + setNameFn(getResult(), name().str()); + } + }]; +} + +def AIE_EventOp: AIE_Op<"event", []> { + let summary = "Event instruction"; + let description = [{ + Event instruction. + }]; + let arguments = (ins ConfinedAttr, IntMaxValue<1>]>:$val); + let results = (outs); + let assemblyFormat = [{ + `(` $val `)` attr-dict + }]; +} + +def AIE_GetStreamOp: AIE_Op<"get_stream", [ + HasParent<"CoreOp"> + ]>, Results<(outs AnyTypeOf<[F32, I32, I<128>]>)> { + let summary = "An op to read from a stream channel/port of a switchbox"; + let description = [{ + An op to read from a stream channel/port of a switchbox. + }]; + + let arguments = (ins AnyInteger:$channel); + let results = (outs AnyTypeOf<[F32, I32, I<128>]>:$stream_value); + + let assemblyFormat = [{ + `(` $channel `:` type($channel) `)` attr-dict `:` type($stream_value) + }]; + + let extraClassDeclaration = [{ + bool isWideStream() { return getStreamValue().getType().isInteger(128); } + bool isFloatStream() { + return llvm::isa(getStreamValue().getType()); + } + }]; +} + +def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { + let summary = "An op to write to a stream channel/port of a switchbox"; + let description = [{ + An op to write to a stream channel/port of a switchbox. + }]; + + let arguments = ( + ins AnyInteger:$channel, + AnyTypeOf<[F32, I32, I<128>]>:$stream_value + ); + + let assemblyFormat = [{ + `(` $channel `:` type($channel) `,` $stream_value `:` type($stream_value) `)` attr-dict + }]; + + let extraClassDeclaration = [{ + bool isWideStream() { return getStreamValue().getType().isInteger(128); } + bool isFloatStream() { + return llvm::isa(getStreamValue().getType()); + } + }]; +} + +def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { + let arguments = ( + ins Index:$source_tile, + Index:$dest_tile + ); + let summary = "A cascade connection between tiles"; + let description = [{ + The `aie.cascade_flow` operation represents a cascade connection between two `aie.tile` operations. + During lowering, this is replaced by `aie.configure_cascade` operations for each `aie.tile` based on + their relative placement to one another. + + Example: + ``` + %tile03 = aie.tile(0, 3) + %tile13 = aie.tile(1, 3) + aie.cascade_flow(%tile03, %tile13) + ``` + }]; + let hasVerifier = 1; + let assemblyFormat = [{ + `(` $source_tile `,` $dest_tile `)` attr-dict + }]; + let extraClassDeclaration = [{ + TileOp getSourceTileOp(); + TileOp getDestTileOp(); + }]; +} + +def AIE_ConfigureCascadeOp: AIE_Op<"configure_cascade", [HasParent<"DeviceOp">]> { + let summary = "An op to configure the input and output directions of the cascade for a single AIE tile"; + let description = [{ + An operation to configure the cascade on a single tile in both the input and the output + directions. + + Example: + ``` + %tile00 = aie.tile(1, 3) + aie.configure_cascade(%tile00, West, East) + ``` + Configures the input cascade port of %tile00 to the West direction, and the output port to the East direction. + }]; + let arguments = ( + ins Index:$tile, + CascadeDir:$inputDir, + CascadeDir:$outputDir + ); + let results = (outs); + let hasVerifier = 1; + let assemblyFormat = [{ `(` $tile `,` $inputDir `,` $outputDir `)` attr-dict }]; +} + +def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascade_value)> { + let summary = "An op to read from a cascading stream from a neighboring core"; + let description = [{ + An op to read from a cascading stream from a neighboring core. + The result type of this operation must have a size that matches the cascade size, + which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> + }]; + let hasVerifier = 1; + let assemblyFormat = [{ `(` `)` attr-dict `:` type($cascade_value) }]; +} + +def AIE_PutCascadeOp: AIE_Op<"put_cascade", [HasParent<"CoreOp">]> { + let summary = "An op to write to a cascading stream from a neighboring core"; + let description = [{ + An op to write to a cascading stream from a neighboring core. + The argument type of this operation must have a size that matches the cascade size, + which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> + }]; + + let arguments = (ins AnyType:$cascade_value); + let hasVerifier = 1; + let assemblyFormat = [{ `(` $cascade_value `:` type($cascade_value) `)` attr-dict }]; +} + +def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp">]> { + let summary = "Runtime allocation information for a single shim DMA"; + let description = [{ + This op exists for cases where shim_dma configuration is performed outside of MLIR-AIE + and hence there is no appropriate dma_start operation to indicate which channel is being + used and on which column the shim_dma is. + + It contains attributes for the sym_name of an operation which generated the shim DMA, + for the DMAChannelDir and channel index, and for the column of the shim tile to which + the originating operation was mapped. + + Example: + ``` + %tile00 = aie.tile(0, 0) + %tile02 = aie.tile(0, 2) + aie.objectfifo @of_in_0 (%tile00, { %tile02 }, 2) : !aie.objectfifo> + ``` + could produce the following allocation info (channel direction MM2S, channel index 1, and shim column 0): + ``` + aie.shim_dma_allocation @of_in_0 (MM2S, 1, 0) + ``` + }]; + + let arguments = ( + ins FlatSymbolRefAttr:$sym_name, + DMAChannelDir:$channel_dir, + I64Attr:$channel_index, + I64Attr:$col, + // If this is set we are using the PLIO in this ShimTile + DefaultValuedAttr:$plio + ); + + let results = (outs); + + let assemblyFormat = [{ + $sym_name `(` $channel_dir `,` $channel_index `,` $col `)` attr-dict + }]; +} + +def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]> { + let summary = "Create a circular buffer or channel between two tiles"; + let description = [{ + The `aie.objectFifo` operation creates a circular buffer established between a producer and one or + more consumers, which are `aie.tile` operations. The`aie.objectFifo` instantiates the given number of + buffers (of given output type) and their locks in the Memory Module of the appropriate tile(s) after + lowering, based on tile-adjacency. These elements represent the conceptual depth of the `objectFifo` or, + more specifically, of its object pool. + + For the producer and for each consumer, a different size (i.e., element number) can be specified as an + array of integer values. This will take effect in the case of consumers placed on tiles non-adjacent to + the producer. Otherwise, the producer size will be applied. If a single size is specified, it will be + applied to both producer and consumers. + + This operation is then converted by the `AIEObjectFifoStatefulTransformPass` into `aie.buffers` and their associated + `aie.locks`. The pass also establishes Flow and DMA operations between the producer and consumer tiles if they are + not adjacent. + + 1-to-1 tile example: + ``` + aie.objectfifo @of1 (%tile12, { %tile23 }, 4 : i32) : !aie.objectfifo> + ``` + This operation creates an `objectFifo` between `%tile12` and `%tile23` of 4 elements, each a buffer of 16 32-bit integers. + Note: If there are no `ObjectFifoAcquireOps` corresponding to this `objectFifo` on the cores of `%tile12` and `%tile23`, + then the depths of the object pools on each tile will be 4, as specified. Otherwise, the cores are scanned and the + highest number of acquired elements (+1 for prefetching) will be used instead, to ensure minimal resource usage. + + 1-to-2 tiles broadcast example: + ``` + aie.objectfifo @of2 (%tile12, { %tile13, %tile23 }, 4 : i32) : !aie.objectfifo> + ``` + This operation creates an `objectFifo` between `%tile12` and tiles `%tile13`, `%tile23` of 4 elements, each a buffer of x16 + 32-bit integers. + + 1-to-2 tiles broadcast with explicit sizes example: + ``` + aie.objectfifo @of3 (%tile12, { %tile13, %tile23 }, [2, 3, 4]) : !aie.objectfifo> + ``` + This operation creates an `objectFifo` between `%tile12`, `%tile13` and `%tile23`. The depths of the `objectFifo` object pool + at each tile are respectively 2, 3 and 4 for tiles `%tile12`, `%tile13` and `%tile23`. This overrides the depth analysis + specified in the first example. + + #### Data Layout Transformations on AIE-ML devices + + On AIE-ML devices, objectFifos can also apply data layout transformations by + using the DMAs n-dimensional address generation scheme. Two transformations + can be applied for an objectFifo: one on the producer side, given by a + `toStream` attribute, and one transformation on the consumer side, given by + a `fromStream` attribute. See the `DMABDOp` documentation for a description + of strides and sizes. The `toStream` and `fromStream` optional attributes + are given directly following the producer or consumer tile declaration. + Different transformations can be specified for each consumer. See example + below. + + Note that using data layout transformations will cause the DMA be used even + between adjacent tiles whose objectFifos would otherwise use shared memory. + + Further note that data layout transforms always apply at a granularity of + `i32`s, irrespective of the used `memref` data type. This is an + architectural requirement. Hence, a stride of 4 always expresses 4 `i32`s, + i.e. 16 bytes. + + The following example shows an objectFifo which transposes a 16x16 matrix of + `i32`s on the producer side using strides and sizes. No transformation is + applied on the consumer side of `%tile13` (in this case the `fromStream` + attribute may also be left off), and a transformation on `%tile23` first gives + all even indices from the stream, followed by all odd indices: + + ``` + aie.objectfifo @of4 (%tile12 toStream [<16, 1>, <16, 16>, <1,1>], + { + %tile13 fromStream [], + %tile23 fromStream [<2, 1>, <128, 2>] + }, 2 : i32 + ) : !aie.objectfifo> + ``` + }]; + + let arguments = ( + ins SymbolNameAttr:$sym_name, + Index:$producerTile, + Variadic:$consumerTiles, + AIE_ObjectFifo_Depth:$elemNumber, + TypeAttrOf:$elemType, + BDDimLayoutArrayAttr:$dimensionsToStream, + BDDimLayoutArrayArrayAttr:$dimensionsFromStreamPerConsumer, + DefaultValuedAttr:$via_DMA, + DefaultValuedAttr:$plio + ); + + let assemblyFormat = [{ + $sym_name + `(` + custom($producerTile, $dimensionsToStream) `,` + `{` + custom($consumerTiles, $dimensionsFromStreamPerConsumer) + `}` + `,` + $elemNumber + `)` attr-dict `:` $elemType + }]; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + int size(int index = 0) { + if (llvm::isa(getElemNumber())) + return llvm::dyn_cast( + llvm::dyn_cast(getElemNumber())[index]) + .getInt(); + else + return llvm::dyn_cast(getElemNumber()).getInt(); + } + + TileOp getProducerTileOp(); + + mlir::StringAttr name() { + return getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName()); + } + }]; + + let builders = [ + OpBuilder<(ins "mlir::StringAttr":$sym_name, "mlir::Value":$producerTile, + "mlir::ValueRange":$consumerTiles, "mlir::Attribute":$elemNumber, "mlir::Type":$elem_type, + CArg<"llvm::ArrayRef", "{}">:$dimensionsToStream, + CArg<"llvm::ArrayRef", "{}">:$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(dimensionsToStream)); + odsState.addAttribute(getDimensionsFromStreamPerConsumerAttrName(odsState.name), + odsBuilder.getAttr(dimensionsFromStreamPerConsumer)); + }]> + ]; +} + +def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { + let summary = "Links two objectFifos through an intermediary tile's DMA"; + let description = [{ + The `aie.objectFifo.link` operation allows to mark two `objectFifos` as linked. This implies that the two `objectFifos` form + one dataflow movement which is split accross multiple `objectFifos`. Specifically, during the `objectFifo` lowering there will + be less memory elements generated at the link point as the two `objectFifos` can share. + + The two `objectFifos` which are linked must have a link point (i.e., a shared AIE tile). + In L1, only `objectFifos` of same size may be linked. In L2, different sized objectFifos can be linked. + + Example: + ``` + aie.objectfifo @of1 (%t70, { %t72 }, 2) : !aie.objectfifo> + aie.objectfifo @of2 (%t72, { %t74 }, 2) : !aie.objectfifo> + aie.objectfifo.link [@of1] -> [@of2] () + ``` + This operation links two `objectFifos` which have tile `%t72` as a link point. + + To achieve a broadcast pattern through the link tile, the output `objectFifo` should have a list of all the consumers tiles. + To achieve a distribute pattern from the link tile, there should be multiple output `objectFifos` in the LinkOp. In this case, + parts will be taken out of the input `objectFifo`'s buffers based on the sizes of the output `objectFifos`, in the order they + were given in the LinkOp. + The join pattern is the exact inverse of the distribute one. + }]; + + let arguments = ( + ins SymbolRefArrayAttr:$fifoIns, + SymbolRefArrayAttr:$fifoOuts + ); + + let hasCustomAssemblyFormat = 1; + + let assemblyFormat = [{ + $fifoIns `->` $fifoOuts `(` `)` attr-dict + }]; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + std::vector getInputObjectFifos(); + std::vector getOutputObjectFifos(); + + bool isJoin() { + return getFifoIns().size() > 1; + } + + bool isDistribute() { + return getFifoOuts().size() > 1; + } + + std::optional getOptionalSharedTile(); + }]; +} + +def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_external_buffers", [ + HasParent<"DeviceOp">, TileElement, IsShimNOCTile + ]> { + let summary = "Registers external buffers to given object fifo shim tile(s) to use in the associated shim DMA(s)"; + let description = [{ + The `aie.objectfifo.register_external_buffers` operation is used to register one or multiple external buffers + to the shim tile(s) used in an `objectFifo` creation. During the `objectFifo` lowering pass, shim DMAs that are + generated for those shim tiles will use the registered external buffers. This is currently done because + external buffers typically have a different size than the AIE buffers which are used in the AIE tiles of the + same `objectFifos`. + + Example: + ``` + aie.objectfifo @of1 (%t70, %t73, 2) : !aie.objectfifo> + %buffer_in_0 = aie.external_buffer : memref<512 x i16> + %buffer_in_1 = aie.external_buffer : memref<512 x i16> + aie.objectfifo.register_external_buffers @of1 (%t70, {buffer_in_0, buffer_in_1}) : (memref<512 x i16>, memref<512 x i16>) + ``` + This operation registers external buffers `%buffer_in_0` and `%buffer_in_1` to use in the shim_dma of shimTile `%t70`. + }]; + + let arguments = ( + ins FlatSymbolRefAttr:$objFifo_name, + Index:$tile, + Variadic:$externalBuffers + ); + + let assemblyFormat = [{ + attr-dict $objFifo_name `(` $tile `,` `{` $externalBuffers `}` `)` `:` `(` type($externalBuffers) `)` + }]; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + TileOp getTileOp(); + ObjectFifoCreateOp getObjectFifo(); + // No results so just use default impl. + using ::mlir::OpAsmOpInterface::Trait::getAsmResultNames; + }]; +} + +def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { + let summary = "Acquire operation to lock and return objects of an ObjectFifo"; + let description = [{ + The `aie.objectFifo.acquire` operation first acquires the locks of the next given number + of objects in the `objectFifo`. The mode it acquires the locks in is chosen based on the port + (producer: acquire for write, consumer: acquire for read). Then, it returns a subview of + the acquired objects which can be used to access them. + + This operation is then converted by the `AIEObjectFifoStatefulTransformPass` into `aie.use_lock` operations on + the locks of the `objectFifo` objects that will be acquired. Under the hood, the operation only performs + new acquires if necessary. For example, if two objects have been acquired in the past and none have yet + to be released by the same process, then performing another acquire operation on the same `objectFifo` + within the same process of size two or less will not result in any new use_lock operations (and for size + greater than two, only (size - 2) use_lock operations will be performed). + + Example: + ``` + %subview = aie.objectfifo.acquire @of1 (Consume, 2) : !aie.objectfifosubview> + ``` + This operation acquires the locks of the next two objects in the `objectFifo` named `@of1` from its consumer + port and returns a subview of the acquired objects. + }]; + + let arguments = ( + ins ObjectFifoPort:$port, + FlatSymbolRefAttr:$objFifo_name, + ConfinedAttr]>:$size + ); + + let results = (outs AIE_ObjectFifoSubviewType:$subview); + + let assemblyFormat = [{ + attr-dict $objFifo_name `(` $port `,` $size `)` `:` type($subview) + }]; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + ObjectFifoCreateOp getObjectFifo(); + int acqNumber() { return getSize(); } + }]; +} + +def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { + let summary = "Release operation for object locks in an ObjectFifo"; + let description = [{ + The `aie.objectFifo.release` operation releases the locks of the given number of objects + in the `objectFifo`. The mode it releases the locks in is chosen based on the `port` + (producer: release for read, consumer: release for write). + + This operation is then converted by the `AIEObjectFifoStatefulTransformPass` into `aie.use_lock` operations. + + Example: + ``` + aie.objectfifo.release @of1 (Produce, 1) + ``` + This operation releases the lock of the next object in the `objectFifo` named `@of1` from producer port. + }]; + + let arguments = ( + ins ObjectFifoPort:$port, + FlatSymbolRefAttr:$objFifo_name, + ConfinedAttr]>:$size + ); + + let assemblyFormat = [{ + attr-dict $objFifo_name `(` $port `,` $size `)` + }]; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + ObjectFifoCreateOp getObjectFifo(); + int relNumber() { return getSize(); } + }]; +} + +def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { + let summary = "ObjectFifoSubview type accessor method"; + let description = [{ + Access the Nth element of a value of `ObjectFifoSubview` type. + + Example: + ``` + %subview = aie.objectfifo.acquire @of1 (Produce, 3) : !aie.objectfifosubview> + %elem = aie.objectfifo.subview.access %subview[0] : !aie.objectfifosubview> -> memref<16xi32> + ``` + In this example, `%elem` is the first object of the subview. Note that this may not correspond to the first element of + the `objectFifo` if other acquire operations took place beforehand. + + }]; + + let arguments = ( + ins AIE_ObjectFifoSubviewType:$subview, + ConfinedAttr]>:$index + ); + + let hasVerifier = 1; + + let results = (outs AnyMemRef:$output); + + let assemblyFormat = [{ + $subview `[` $index `]` attr-dict `:` type($subview) `->` type($output) + }]; + + // Allow building an AIE_ObjectFifoSubviewAccessOp with just a subview value and an index. + let builders = [ + OpBuilder<(ins "mlir::Value":$subview, "size_t":$index)> + ]; +} + +def AIE_ObjectFifoRegisterProcessOp: AIE_Op<"objectfifo.register_process", []> { + let summary = "Operation that produces the acquire/release patterns for a process registered to an objectFifo"; + let description = [{ + The `aie.registerProcess` operation allows the user to register a function to an `objectFifo` along with its + acquire and release patterns. These patterns will be used to generate a sequence of acquires and releases + on the `objectFifo` elements. This generated sequence is often in the form of a for loop, however, in the case + of cyclo-static patterns only the repetition of same number accesses and releases will generate a for loop. + This may result in multiple for loops of different sizes being generated. If there is no repetition, then no + loops will be generated. + + Example: + ``` + aie.objectfifo @of1 (%t72, %t73, 2) : !aie.objectfifo> + %length = arith.constant 10 : index + %acquirePatternProducer = arith.constant dense<[1, 2, 2, 0]> : tensor<4xi32> + %releasePatternProducer = arith.constant dense<[0, 1, 1, 2]> : tensor<4xi32> + func @producer_work(%input : !aie.objectfifosubview>) -> () { ... } + + aie.objectfifo.register_process @of1 (Produce, %acquirePatternProducer : tensor<4xi32>, %releasePatternProducer : tensor<4xi32>, @producer_work, %length) + ``` + This operation registers function @producer_work and associated patterns to the produce end of @of1. + @producer_work will be called with the subviews produced when acquiring elements from @of1 following the acquire pattern. + + If the input patterns are static (only one element) then the length of the produced for loop will be that of the input `%length`. + If the input patterns are cyclo-static then they must be of the same size. + }]; + + let arguments = ( + ins ObjectFifoPort:$port, + FlatSymbolRefAttr:$objFifo_name, + I32Tensor:$acquirePatternTensor, + I32Tensor:$releasePatternTensor, + FlatSymbolRefAttr:$callee, + Index:$length + ); + + let assemblyFormat = [{ + attr-dict $objFifo_name `(` + $port `,` + $acquirePatternTensor `:` type($acquirePatternTensor) `,` + $releasePatternTensor `:` type($releasePatternTensor) `,` + $callee `,` $length + `)` + }]; + + let hasVerifier = 1; + + let extraClassDeclaration = [{ + ObjectFifoCreateOp getObjectFifo(); + + mlir::DenseIntElementsAttr getAcquirePattern() { + return llvm::cast(getAcquirePatternTensor() + .getDefiningOp() + .getValue()); + } + + mlir::DenseIntElementsAttr getReleasePattern() { + return llvm::cast(getReleasePatternTensor() + .getDefiningOp() + .getValue()); + } + + int getProcessLength() { + return llvm::cast(getLength() + .getDefiningOp() + .getValue()) + .getInt(); + } + }]; +} + +#endif // AIE_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp b/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp new file mode 100644 index 000000000..0f9d4e48b --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp @@ -0,0 +1,709 @@ +//===- AIETargetModel.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 +// +// (c) Copyright 2019 Xilinx Inc. +// (c) Copyright 2023 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#include "AIETargetModel.h" +#include "llvm/ADT/SmallSet.h" + +using namespace llvm; + +namespace xilinx { +namespace AIE { +AIETargetModel::~AIETargetModel() = default; + +/// +/// AIE1 TargetModel +/// + +AIEArch AIE1TargetModel::getTargetArch() const { return AIEArch::AIE1; } + +// Return the tile ID of the memory to the west of the given tile, if it exists. +std::optional AIE1TargetModel::getMemWest(TileID src) const { + bool isEvenRow = ((src.row % 2) == 0); + std::optional ret; + if (isEvenRow) + ret = src; + else + ret = {src.col - 1, src.row}; + if (!isValidTile(*ret)) + ret.reset(); + return ret; +} + +// Return the tile ID of the memory to the west of the given tile, if it exists. +std::optional AIE1TargetModel::getMemEast(TileID src) const { + bool isEvenRow = (src.row % 2) == 0; + std::optional ret; + if (isEvenRow) + ret = {src.col + 1, src.row}; + else + ret = src; + if (!isValidTile(*ret)) + ret.reset(); + return ret; +} + +// Return the tile ID of the memory to the west of the given tile, if it exists. +std::optional AIE1TargetModel::getMemNorth(TileID src) const { + std::optional ret({src.col, src.row + 1}); + if (!isValidTile(*ret)) + ret.reset(); + return ret; +} + +std::optional AIE1TargetModel::getMemSouth(TileID src) const { + std::optional ret({src.col, src.row - 1}); + // The first row doesn't have a tile memory south + if (!isValidTile(*ret) || ret->row == 0) + ret.reset(); + return ret; +} + +bool AIE1TargetModel::isMemWest(int srcCol, int srcRow, int dstCol, + int dstRow) const { + bool IsEvenRow = (srcRow % 2) == 0; + return (IsEvenRow && isInternal(srcCol, srcRow, dstCol, dstRow)) || + (!IsEvenRow && isWest(srcCol, srcRow, dstCol, dstRow)); +} + +bool AIE1TargetModel::isMemEast(int srcCol, int srcRow, int dstCol, + int dstRow) const { + bool IsEvenRow = (srcRow % 2) == 0; + return (!IsEvenRow && isInternal(srcCol, srcRow, dstCol, dstRow)) || + (IsEvenRow && isEast(srcCol, srcRow, dstCol, dstRow)); +} + +bool AIE1TargetModel::isMemNorth(int srcCol, int srcRow, int dstCol, + int dstRow) const { + return isNorth(srcCol, srcRow, dstCol, dstRow); +} + +bool AIE1TargetModel::isMemSouth(int srcCol, int srcRow, int dstCol, + int dstRow) const { + return isSouth(srcCol, srcRow, dstCol, dstRow); +} + +bool AIE1TargetModel::isLegalMemAffinity(int coreCol, int coreRow, int memCol, + int memRow) const { + bool IsEvenRow = ((coreRow % 2) == 0); + + bool IsMemWest = (isWest(coreCol, coreRow, memCol, memRow) && !IsEvenRow) || + (isInternal(coreCol, coreRow, memCol, memRow) && IsEvenRow); + + bool IsMemEast = (isEast(coreCol, coreRow, memCol, memRow) && IsEvenRow) || + (isInternal(coreCol, coreRow, memCol, memRow) && !IsEvenRow); + + bool IsMemNorth = isNorth(coreCol, coreRow, memCol, memRow); + bool IsMemSouth = isSouth(coreCol, coreRow, memCol, memRow); + + return IsMemSouth || IsMemNorth || IsMemWest || IsMemEast; +} + +uint32_t +AIE1TargetModel::getNumDestSwitchboxConnections(int col, int row, + WireBundle bundle) const { + if (isShimNOCTile(col, row) || isShimPLTile(col, row)) + switch (bundle) { + case WireBundle::FIFO: + return 2; + case WireBundle::North: + return 6; + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 6; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Ctrl: + return isShimNOCTile(col, row) ? 1 : 0; + default: + return 0; + } + + switch (bundle) { + case WireBundle::Core: + case WireBundle::DMA: + case WireBundle::FIFO: + return 2; + case WireBundle::North: { + if (row == rows() - 1) + return 0; + return 6; + } + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 4; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Ctrl: + return 1; + default: + return 0; + } +} + +uint32_t +AIE1TargetModel::getNumSourceSwitchboxConnections(int col, int row, + WireBundle bundle) const { + if (isShimNOCTile(col, row) || isShimPLTile(col, row)) + switch (bundle) { + case WireBundle::FIFO: + return 2; + case WireBundle::North: + return 4; + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 8; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Trace: + return 1; + case WireBundle::Ctrl: + return isShimNOCTile(col, row) ? 1 : 0; + default: + return 0; + } + + switch (bundle) { + case WireBundle::Core: + case WireBundle::DMA: + case WireBundle::FIFO: + return 2; + case WireBundle::North: { + if (row == rows() - 1) + return 0; + return 4; + } + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 6; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Trace: + return 2; + case WireBundle::Ctrl: + return 1; + default: + return 0; + } +} +uint32_t +AIE1TargetModel::getNumDestShimMuxConnections(int col, int row, + WireBundle bundle) const { + if (isShimNOCorPLTile(col, row)) + switch (bundle) { + case WireBundle::DMA: + return 2; + case WireBundle::NOC: + return 4; + case WireBundle::PLIO: + return 6; + case WireBundle::South: + return 8; // Connection to the south port of the stream switch + default: + return 0; + } + return 0; +} +uint32_t +AIE1TargetModel::getNumSourceShimMuxConnections(int col, int row, + WireBundle bundle) const { + if (isShimNOCorPLTile(col, row)) + switch (bundle) { + case WireBundle::DMA: + return 2; + case WireBundle::NOC: + return 4; + case WireBundle::PLIO: + return 8; + case WireBundle::South: + return 6; // Connection to the south port of the stream switch + default: + return 0; + } + return 0; +} + +bool AIE1TargetModel::isLegalTileConnection(int col, int row, + WireBundle srcBundle, int srcChan, + WireBundle dstBundle, + int dstChan) const { + // Check Channel Id within the range + if (srcChan >= int(getNumSourceSwitchboxConnections(col, row, srcBundle))) + return false; + if (dstChan >= int(getNumDestSwitchboxConnections(col, row, dstBundle))) + return false; + + // Memtile + if (isMemTile(col, row)) { + return false; + } + // Shimtile + else if (isShimNOCorPLTile(col, row)) { + if (srcBundle == WireBundle::Trace) + return dstBundle == WireBundle::South; + else + return true; + } + // Coretile + else if (isCoreTile(col, row)) { + if (srcBundle == WireBundle::Trace) + return dstBundle == WireBundle::South; + else + return true; + } + return false; +} + +/// +/// AIE2 TargetModel +/// + +AIEArch AIE2TargetModel::getTargetArch() const { return AIEArch::AIE2; } + +// Return the tile ID of the memory to the west of the given tile, if it exists. +std::optional AIE2TargetModel::getMemWest(TileID src) const { + std::optional ret({src.col - 1, src.row}); + if (!isValidTile(*ret)) + ret.reset(); + return ret; +} + +// Return the tile ID of the memory to the east of the given tile (ie self), if +// it exists. +std::optional AIE2TargetModel::getMemEast(TileID src) const { + std::optional ret = src; + if (!isValidTile(*ret)) + ret.reset(); + return ret; +} + +// Return the tile ID of the memory to the north of the given tile, if it +// exists. +std::optional AIE2TargetModel::getMemNorth(TileID src) const { + std::optional ret({src.col, src.row + 1}); + if (!isValidTile(*ret)) + ret.reset(); + return ret; +} + +std::optional AIE2TargetModel::getMemSouth(TileID src) const { + std::optional ret({src.col, src.row - 1}); + // The first row doesn't have a tile memory south + // Memtiles don't have memory adjacency to neighboring core tiles. + if (!isValidTile(*ret) || ret->row == 0 || isMemTile(ret->col, ret->row)) + ret.reset(); + return ret; +} + +bool AIE2TargetModel::isMemWest(int srcCol, int srcRow, int dstCol, + int dstRow) const { + return isWest(srcCol, srcRow, dstCol, dstRow); +} + +bool AIE2TargetModel::isMemEast(int srcCol, int srcRow, int dstCol, + int dstRow) const { + return isInternal(srcCol, srcRow, dstCol, dstRow); +} + +bool AIE2TargetModel::isMemNorth(int srcCol, int srcRow, int dstCol, + int dstRow) const { + return isNorth(srcCol, srcRow, dstCol, dstRow); +} + +bool AIE2TargetModel::isMemSouth(int srcCol, int srcRow, int dstCol, + int dstRow) const { + return isSouth(srcCol, srcRow, dstCol, dstRow); +} + +bool AIE2TargetModel::isLegalMemAffinity(int coreCol, int coreRow, int memCol, + int memRow) const { + + bool IsMemWest = isMemWest(coreCol, coreRow, memCol, memRow); + bool IsMemEast = isMemEast(coreCol, coreRow, memCol, memRow); + bool IsMemNorth = isMemNorth(coreCol, coreRow, memCol, memRow); + bool IsMemSouth = isMemSouth(coreCol, coreRow, memCol, memRow); + + if (isMemTile(coreCol, coreRow)) + return isEast(coreCol, coreRow, memCol, memRow) || + isInternal(coreCol, coreRow, memCol, memRow) || + isWest(coreCol, coreRow, memCol, memRow); + return (IsMemSouth && !isMemTile(memCol, memRow)) || IsMemNorth || + IsMemWest || IsMemEast; +} + +uint32_t +AIE2TargetModel::getNumDestSwitchboxConnections(int col, int row, + WireBundle bundle) const { + if (isMemTile(col, row)) + switch (bundle) { + case WireBundle::DMA: + case WireBundle::North: + return 6; + case WireBundle::South: + return 4; + case WireBundle::Ctrl: + return 1; + default: + return 0; + } + + if (isShimNOCTile(col, row) || isShimPLTile(col, row)) + switch (bundle) { + case WireBundle::FIFO: + return 1; + case WireBundle::North: + return 6; + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 6; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Ctrl: + return isShimNOCTile(col, row) ? 1 : 0; + default: + return 0; + } + + switch (bundle) { + case WireBundle::Core: + return 1; + case WireBundle::DMA: + return 2; + case WireBundle::FIFO: + return 1; + case WireBundle::North: { + if (row == rows() - 1) + return 0; + return 6; + } + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 4; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Ctrl: + return 1; + default: + return 0; + } +} + +uint32_t +AIE2TargetModel::getNumSourceSwitchboxConnections(int col, int row, + WireBundle bundle) const { + if (isMemTile(col, row)) + switch (bundle) { + case WireBundle::DMA: + return 6; + case WireBundle::North: + return 4; + case WireBundle::South: + return 6; + case WireBundle::Trace: + case WireBundle::Ctrl: + return 1; + default: + return 0; + } + + if (isShimNOCTile(col, row) || isShimPLTile(col, row)) + switch (bundle) { + case WireBundle::FIFO: + return 1; + case WireBundle::North: + return 4; + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 8; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Trace: + return 1; + case WireBundle::Ctrl: + return isShimNOCTile(col, row) ? 1 : 0; + default: + return 0; + } + + // compute/core tile + switch (bundle) { + case WireBundle::Core: + return 1; + case WireBundle::DMA: + return 2; + case WireBundle::FIFO: + return 1; + case WireBundle::North: { + if (row == rows() - 1) + return 0; + return 4; + } + case WireBundle::West: { + if (col == 0) + return 0; + return 4; + } + case WireBundle::South: + return 6; + case WireBundle::East: { + if (col == columns() - 1) + return 0; + return 4; + } + case WireBundle::Trace: + // Port 0: core trace. Port 1: memory trace. + return 2; + case WireBundle::Ctrl: + return 1; + default: + return 0; + } +} + +uint32_t +AIE2TargetModel::getNumDestShimMuxConnections(int col, int row, + WireBundle bundle) const { + if (isShimNOCorPLTile(col, row)) + switch (bundle) { + case WireBundle::DMA: + return 2; + case WireBundle::NOC: + return 4; + case WireBundle::PLIO: + return 6; + case WireBundle::South: + return 8; // Connection to the south port of the stream switch + default: + return 0; + } + + return 0; +} + +uint32_t +AIE2TargetModel::getNumSourceShimMuxConnections(int col, int row, + WireBundle bundle) const { + if (isShimNOCorPLTile(col, row)) + switch (bundle) { + case WireBundle::DMA: + return 2; + case WireBundle::NOC: + return 4; + case WireBundle::PLIO: + return 8; + case WireBundle::South: + return 6; // Connection to the south port of the stream switch + default: + return 0; + } + + return 0; +} + +bool AIE2TargetModel::isLegalTileConnection(int col, int row, + WireBundle srcBundle, int srcChan, + WireBundle dstBundle, + int dstChan) const { + // Check Channel Id within the range + if (srcChan >= int(getNumSourceSwitchboxConnections(col, row, srcBundle))) + return false; + if (dstChan >= int(getNumDestSwitchboxConnections(col, row, dstBundle))) + return false; + + // Lambda function to check if a bundle is in a list + auto isBundleInList = [](WireBundle bundle, + std::initializer_list bundles) { + return std::find(bundles.begin(), bundles.end(), bundle) != bundles.end(); + }; + + // Memtile + if (isMemTile(col, row)) { + if (srcBundle == WireBundle::DMA) { + if (dstBundle == WireBundle::DMA) + return srcChan == dstChan; + if (isBundleInList(dstBundle, {WireBundle::Ctrl, WireBundle::South, + WireBundle::North})) + return true; + } + if (srcBundle == WireBundle::Ctrl) { + if (dstBundle == WireBundle::DMA) + return dstChan == 5; + if (isBundleInList(dstBundle, {WireBundle::South, WireBundle::North})) + return true; + } + if (isBundleInList(srcBundle, {WireBundle::South, WireBundle::North})) { + if (isBundleInList(dstBundle, {WireBundle::DMA, WireBundle::Ctrl})) + return true; + if (isBundleInList(dstBundle, {WireBundle::South, WireBundle::North})) + return srcChan == dstChan; + } + if (srcBundle == WireBundle::Trace) { + if (dstBundle == WireBundle::DMA) + return dstChan == 5; + if (dstBundle == WireBundle::South) + return true; + } + } + // Shimtile + else if (isShimNOCorPLTile(col, row)) { + if (srcBundle == WireBundle::Ctrl) + return dstBundle != WireBundle::Ctrl; + if (isBundleInList(srcBundle, {WireBundle::FIFO, WireBundle::South})) + return isBundleInList(dstBundle, {WireBundle::Ctrl, WireBundle::FIFO, + WireBundle::South, WireBundle::West, + WireBundle::North, WireBundle::East}); + if (isBundleInList(srcBundle, + {WireBundle::West, WireBundle::North, WireBundle::East})) + return (srcBundle == dstBundle) + ? (srcChan == dstChan) + : isBundleInList(dstBundle, + {WireBundle::Ctrl, WireBundle::FIFO, + WireBundle::South, WireBundle::West, + WireBundle::North, WireBundle::East}); + if (srcBundle == WireBundle::Trace) { + if (isBundleInList(dstBundle, {WireBundle::FIFO, WireBundle::South})) + return true; + if (isBundleInList(dstBundle, {WireBundle::West, WireBundle::East})) + return dstChan == 0; + } + } + // Coretile + else if (isCoreTile(col, row)) { + if (isBundleInList(srcBundle, + {WireBundle::DMA, WireBundle::FIFO, WireBundle::South, + WireBundle::West, WireBundle::North, WireBundle::East})) + if (isBundleInList(dstBundle, + {WireBundle::Core, WireBundle::DMA, WireBundle::Ctrl, + WireBundle::FIFO, WireBundle::South, WireBundle::West, + WireBundle::North, WireBundle::East})) + return (srcBundle == dstBundle) ? (srcChan == dstChan) : true; + if (srcBundle == WireBundle::Core) + return dstBundle != WireBundle::Core; + if (srcBundle == WireBundle::Ctrl) + return dstBundle != WireBundle::Ctrl && dstBundle != WireBundle::DMA; + if (srcBundle == WireBundle::Trace) { + if (dstBundle == WireBundle::DMA) + return dstChan == 0; + if (isBundleInList(dstBundle, {WireBundle::FIFO, WireBundle::South})) + return true; + } + } + return false; +} + +void AIETargetModel::validate() const { + // Every tile in a shimtile row must be a shimtile, and can only be one type + // of shim tile. + for (int j = 0; j < columns(); j++) { + assert(!isMemTile(j, 0) && (isShimPLTile(j, 0) || isShimNOCTile(j, 0)) && + !isCoreTile(j, 0)); + assert(isShimPLTile(j, 0) ^ isShimNOCTile(j, 0)); + } + + // Every tile in a memtile row must be a memtile. + for (int i = 1; i < 1 + static_cast(getNumMemTileRows()); i++) + for (int j = 0; j < columns(); j++) + assert(isMemTile(j, i) && !isShimPLTile(j, i) && !isShimNOCTile(j, i) && + !isCoreTile(j, i)); + + // Every other tile is a coretile. + for (int i = 1 + getNumMemTileRows(); i < rows(); i++) + for (int j = 0; j < columns(); j++) + assert(!isMemTile(j, i) && !isShimPLTile(j, i) && !isShimNOCTile(j, i) && + isCoreTile(j, i)); + + // Looking North, buses must match + for (int i = 0; i < rows() - 1; i++) + for (int j = 0; j < columns(); j++) + assert(getNumSourceSwitchboxConnections(j, i, WireBundle::North) == + getNumDestSwitchboxConnections(j, i + 1, WireBundle::South)); + // Looking South, buses must match + for (int i = 1; i < rows(); i++) + for (int j = 0; j < columns(); j++) + assert(getNumSourceSwitchboxConnections(j, i, WireBundle::South) == + getNumDestSwitchboxConnections(j, i - 1, WireBundle::North)); + // Looking East, buses must match + for (int i = 0; i < rows(); i++) + for (int j = 0; j < columns() - 1; j++) + assert(getNumSourceSwitchboxConnections(j, i, WireBundle::East) == + getNumDestSwitchboxConnections(j + 1, i, WireBundle::West)); + // Looking West, buses must match + for (int i = 0; i < rows(); i++) + for (int j = 1; j < columns(); j++) + assert(getNumSourceSwitchboxConnections(j, i, WireBundle::West) == + getNumDestSwitchboxConnections(j - 1, i, WireBundle::East)); + // Edges have no connections + for (int j = 0; j < columns(); j++) + assert(getNumSourceSwitchboxConnections(j, rows() - 1, WireBundle::North) == + 0); + for (int i = 0; i < rows(); i++) + assert(getNumSourceSwitchboxConnections(columns() - 1, i, + WireBundle::East) == 0); + for (int i = 0; i < rows(); i++) + assert(getNumSourceSwitchboxConnections(0, i, WireBundle::West) == 0); + + // FIFOS are consistent + for (int i = 0; i < rows(); i++) + for (int j = 0; j < columns(); j++) + assert(getNumSourceSwitchboxConnections(j, i, WireBundle::FIFO) == + getNumDestSwitchboxConnections(j, i, WireBundle::FIFO)); +} + +} // namespace AIE +} // namespace xilinx diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h b/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h new file mode 100644 index 000000000..ad8161c0a --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h @@ -0,0 +1,529 @@ +//===- AIETargetModel.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 2023 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_AIE_DEVICEMODEL_H +#define MLIR_AIE_DEVICEMODEL_H + +#include "AIEEnums.h" + +#include "llvm/ADT/DenseSet.h" + +#include + +namespace xilinx::AIE { + +using TileID = struct TileID { + // friend definition (will define the function as a non-member function in the + // namespace surrounding the class). + friend std::ostream &operator<<(std::ostream &os, const TileID &s) { + os << "TileID(" << s.col << ", " << s.row << ")"; + return os; + } + + friend std::string to_string(const TileID &s) { + std::ostringstream ss; + ss << s; + return ss.str(); + } + + friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const TileID &s) { + os << to_string(s); + return os; + } + + // Imposes a lexical order on TileIDs. + inline bool operator<(const TileID &rhs) const { + return std::tie(col, row) < std::tie(rhs.col, rhs.row); + } + + bool operator==(const TileID &rhs) const { + return std::tie(col, row) == std::tie(rhs.col, rhs.row); + } + + bool operator!=(const TileID &rhs) const { return !(*this == rhs); } + + int col, row; +}; + +class AIETargetModel { +public: + AIETargetModel() = default; + + virtual ~AIETargetModel(); + + /// Return the target architecture. + virtual AIEArch getTargetArch() const = 0; + + /// Return the data bus width of the device. + virtual uint32_t getAddressGenGranularity() const = 0; + + /// Return the number of columns in the device. + virtual int columns() const = 0; + + /// Return the number of rows in the device. + virtual int rows() const = 0; + + /// Return true if the given tile is a 'Core' tile. These tiles + /// include a Core, TileDMA, tile memory, and stream connections. + virtual bool isCoreTile(int col, int row) const = 0; + + /// Return true if the given tile is an AIE2 'Memory' tile. These tiles + /// include a TileDMA, tile memory, and stream connections, but no core. + virtual bool isMemTile(int col, int row) const = 0; + + /// Return true if the given tile is a Shim NOC tile. These tiles include a + /// ShimDMA and a connection to the memory-mapped NOC. They do not contain + /// any memory. + virtual bool isShimNOCTile(int col, int row) const = 0; + + /// Return true if the given tile is a Shim PL interface tile. These + /// tiles do not include a ShimDMA and instead include connections to the PL. + /// They do not contain any memory. + virtual bool isShimPLTile(int col, int row) const = 0; + + /// Return true if the given tile is either a Shim NOC or a Shim PL interface + /// tile. + virtual bool isShimNOCorPLTile(int col, int row) const = 0; + + /// Return true if the given tile ID is valid. + virtual bool isValidTile(TileID src) const { + return src.col >= 0 && src.col < columns() && src.row >= 0 && + src.row < rows(); + } + + /// Return the tile ID of the memory to the west of the given tile, if it + /// exists. + virtual std::optional getMemWest(TileID src) const = 0; + /// Return the tile ID of the memory to the east of the given tile, if it + /// exists. + virtual std::optional getMemEast(TileID src) const = 0; + /// Return the tile ID of the memory to the north of the given tile, if it + /// exists. + virtual std::optional getMemNorth(TileID src) const = 0; + /// Return the tile ID of the memory to the south of the given tile, if it + /// exists. + virtual std::optional getMemSouth(TileID src) const = 0; + + /// Return true if src is the internal memory of dst + bool isInternal(int srcCol, int srcRow, int dstCol, int dstRow) const { + return srcCol == dstCol && srcRow == dstRow; + } + + /// Return true if src is West of dst + bool isWest(int srcCol, int srcRow, int dstCol, int dstRow) const { + return srcCol == dstCol + 1 && srcRow == dstRow; + } + + /// Return true if src is East of dst + bool isEast(int srcCol, int srcRow, int dstCol, int dstRow) const { + return srcCol == dstCol - 1 && srcRow == dstRow; + } + + /// Return true if src is North of dst + bool isNorth(int srcCol, int srcRow, int dstCol, int dstRow) const { + return srcCol == dstCol && srcRow == dstRow - 1; + } + + /// Return true if src is South of dst + bool isSouth(int srcCol, int srcRow, int dstCol, int dstRow) const { + return srcCol == dstCol && srcRow == dstRow + 1; + } + + /// Return true if src has a memory tile which is West of dst + virtual bool isMemWest(int srcCol, int srcRow, int dstCol, + int dstRow) const = 0; + /// Return true if src has a memory tile which is East of dst + virtual bool isMemEast(int srcCol, int srcRow, int dstCol, + int dstRow) const = 0; + /// Return true if src has a memory tile which is North of dst + virtual bool isMemNorth(int srcCol, int srcRow, int dstCol, + int dstRow) const = 0; + /// Return true if src has a memory tile which is South of dst + virtual bool isMemSouth(int srcCol, int srcRow, int dstCol, + int dstRow) const = 0; + + /// Return true if core can access the memory in mem + virtual bool isLegalMemAffinity(int coreCol, int coreRow, int memCol, + int memRow) const = 0; + + /// Return the base address in the local address map of different memories. + virtual uint32_t getMemInternalBaseAddress(TileID src) const = 0; + virtual uint32_t getMemSouthBaseAddress() const = 0; + virtual uint32_t getMemWestBaseAddress() const = 0; + virtual uint32_t getMemNorthBaseAddress() const = 0; + virtual uint32_t getMemEastBaseAddress() const = 0; + + /// Return the size (in bytes) of the local data memory of a core. + virtual uint32_t getLocalMemorySize() const = 0; + + /// Return the size (in bits) of the accumulator/cascade. + virtual uint32_t getAccumulatorCascadeSize() const = 0; + + /// Return the number of lock objects + virtual uint32_t getNumLocks(int col, int row) const = 0; + + /// Return the number of buffer descriptors supported by the DMA in the given + /// tile. + virtual uint32_t getNumBDs(int col, int row) const = 0; + + virtual uint32_t getNumMemTileRows() const = 0; + /// Return the size (in bytes) of a MemTile. + virtual uint32_t getMemTileSize() const = 0; + /// Return the number of destinations of connections inside a switchbox. These + /// are the targets of connect operations in the switchbox. + virtual uint32_t getNumDestSwitchboxConnections(int col, int row, + WireBundle bundle) const = 0; + /// Return the number of sources of connections inside a switchbox. These are + /// the origins of connect operations in the switchbox. + virtual uint32_t + getNumSourceSwitchboxConnections(int col, int row, + WireBundle bundle) const = 0; + /// Return the number of destinations of connections inside a shimmux. These + /// are the targets of connect operations in the switchbox. + virtual uint32_t getNumDestShimMuxConnections(int col, int row, + WireBundle bundle) const = 0; + /// Return the number of sources of connections inside a shimmux. These are + /// the origins of connect operations in the switchbox. + virtual uint32_t getNumSourceShimMuxConnections(int col, int row, + WireBundle bundle) const = 0; + + // Return true if the stream switch connection is legal, false otherwise. + virtual bool isLegalTileConnection(int col, int row, WireBundle srcBundle, + int srcChan, WireBundle dstBundle, + int dstChan) const = 0; + + // Run consistency checks on the target model. + void validate() const; + + // Return true if this is an NPU-based device + // There are several special cases for handling the NPU at the moment. + virtual bool isNPU() const { return false; } + + // Return the bit offset of the column within a tile address. + // This is used to compute the control address of a tile from it's column + // location. + virtual uint32_t getColumnShift() const = 0; + + // Return the bit offset of the row within a tile address. + // This is used to compute the control address of a tile from it's row + // location. + virtual uint32_t getRowShift() const = 0; +}; + +class AIE1TargetModel : public AIETargetModel { +public: + AIE1TargetModel() = default; + + bool isCoreTile(int col, int row) const override { return row > 0; } + bool isMemTile(int col, int row) const override { return false; } + + AIEArch getTargetArch() const override; + + std::optional getMemWest(TileID src) const override; + std::optional getMemEast(TileID src) const override; + std::optional getMemNorth(TileID src) const override; + std::optional getMemSouth(TileID src) const override; + + bool isMemWest(int srcCol, int srcRow, int dstCol, int dstRow) const override; + bool isMemEast(int srcCol, int srcRow, int dstCol, int dstRow) const override; + bool isMemNorth(int srcCol, int srcRow, int dstCol, + int dstRow) const override; + bool isMemSouth(int srcCol, int srcRow, int dstCol, + int dstRow) const override; + + bool isLegalMemAffinity(int coreCol, int coreRow, int memCol, + int memRow) const override; + + uint32_t getMemInternalBaseAddress(TileID src) const override { + if (src.row % 2 == 0) + // Internal is West + return getMemWestBaseAddress(); + // Internal is East + return getMemEastBaseAddress(); + } + + uint32_t getMemSouthBaseAddress() const override { return 0x00020000; } + uint32_t getMemWestBaseAddress() const override { return 0x00028000; } + uint32_t getMemNorthBaseAddress() const override { return 0x00030000; } + uint32_t getMemEastBaseAddress() const override { return 0x00038000; } + uint32_t getLocalMemorySize() const override { return 0x00008000; } + uint32_t getAccumulatorCascadeSize() const override { return 384; } + uint32_t getNumLocks(int col, int row) const override { return 16; } + uint32_t getNumBDs(int col, int row) const override { return 16; } + uint32_t getNumMemTileRows() const override { return 0; } + uint32_t getMemTileSize() const override { return 0; } + + uint32_t getNumDestSwitchboxConnections(int col, int row, + WireBundle bundle) const override; + uint32_t getNumSourceSwitchboxConnections(int col, int row, + WireBundle bundle) const override; + uint32_t getNumDestShimMuxConnections(int col, int row, + WireBundle bundle) const override; + uint32_t getNumSourceShimMuxConnections(int col, int row, + WireBundle bundle) const override; + bool isLegalTileConnection(int col, int row, WireBundle srcBundle, + int srcChan, WireBundle dstBundle, + int dstChan) const override; + + uint32_t getColumnShift() const override { return 23; } + uint32_t getRowShift() const override { return 18; } +}; + +class AIE2TargetModel : public AIETargetModel { +public: + AIE2TargetModel() = default; + + AIEArch getTargetArch() const override; + + uint32_t getAddressGenGranularity() const override { return 32; } + + std::optional getMemWest(TileID src) const override; + std::optional getMemEast(TileID src) const override; + std::optional getMemNorth(TileID src) const override; + std::optional getMemSouth(TileID src) const override; + + bool isMemWest(int srcCol, int srcRow, int dstCol, int dstRow) const override; + bool isMemEast(int srcCol, int srcRow, int dstCol, int dstRow) const override; + bool isMemNorth(int srcCol, int srcRow, int dstCol, + int dstRow) const override; + bool isMemSouth(int srcCol, int srcRow, int dstCol, + int dstRow) const override; + + bool isLegalMemAffinity(int coreCol, int coreRow, int memCol, + int memRow) const override; + + uint32_t getMemInternalBaseAddress(TileID src) const override { + return getMemEastBaseAddress(); + } + + uint32_t getMemSouthBaseAddress() const override { return 0x00040000; } + uint32_t getMemWestBaseAddress() const override { return 0x00050000; } + uint32_t getMemNorthBaseAddress() const override { return 0x00060000; } + uint32_t getMemEastBaseAddress() const override { return 0x00070000; } + uint32_t getLocalMemorySize() const override { return 0x00010000; } + uint32_t getAccumulatorCascadeSize() const override { return 512; } + + uint32_t getNumLocks(int col, int row) const override { + return isMemTile(col, row) ? 64 : 16; + } + + uint32_t getNumBDs(int col, int row) const override { + return isMemTile(col, row) ? 48 : 16; + } + + uint32_t getMemTileSize() const override { return 0x00080000; } + + uint32_t getNumDestSwitchboxConnections(int col, int row, + WireBundle bundle) const override; + uint32_t getNumSourceSwitchboxConnections(int col, int row, + WireBundle bundle) const override; + uint32_t getNumDestShimMuxConnections(int col, int row, + WireBundle bundle) const override; + uint32_t getNumSourceShimMuxConnections(int col, int row, + WireBundle bundle) const override; + bool isLegalTileConnection(int col, int row, WireBundle srcBundle, + int srcChan, WireBundle dstBundle, + int dstChan) const override; + + uint32_t getColumnShift() const override { return 25; } + uint32_t getRowShift() const override { return 20; } +}; + +class VC1902TargetModel : public AIE1TargetModel { + llvm::SmallDenseSet nocColumns = { + 2, 3, 6, 7, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 46, 47}; + +public: + VC1902TargetModel() = default; + + uint32_t getAddressGenGranularity() const override { return 32; } + + int columns() const override { return 50; } + + int rows() const override { return 9; /* One Shim row and 8 Core rows. */ } + + bool isShimNOCTile(int col, int row) const override { + return row == 0 && nocColumns.contains(col); + } + + bool isShimPLTile(int col, int row) const override { + return row == 0 && !nocColumns.contains(col); + } + + bool isShimNOCorPLTile(int col, int row) const override { + return isShimNOCTile(col, row) || isShimPLTile(col, row); + } +}; + +class VE2302TargetModel : public AIE2TargetModel { + llvm::SmallDenseSet nocColumns = {2, 3, 6, 7, 10, 11}; + +public: + VE2302TargetModel() = default; + + int columns() const override { return 17; } + + int rows() const override { + return 4; /* One Shim row, 1 memtile rows, and 2 Core rows. */ + } + + bool isCoreTile(int col, int row) const override { return row > 1; } + bool isMemTile(int col, int row) const override { return row == 1; } + + bool isShimNOCTile(int col, int row) const override { + return row == 0 && nocColumns.contains(col); + } + + bool isShimPLTile(int col, int row) const override { + return row == 0 && !nocColumns.contains(col); + } + + bool isShimNOCorPLTile(int col, int row) const override { + return isShimNOCTile(col, row) || isShimPLTile(col, row); + } + + uint32_t getNumMemTileRows() const override { return 1; } +}; + +class VE2802TargetModel : public AIE2TargetModel { + llvm::SmallDenseSet nocColumns = {2, 3, 6, 7, 14, 15, + 22, 23, 30, 31, 34, 35}; + +public: + VE2802TargetModel() = default; + + int columns() const override { return 38; } + + int rows() const override { + return 11; /* One Shim row, 2 memtile rows, and 8 Core rows. */ + } + + bool isCoreTile(int col, int row) const override { return row > 2; } + + bool isMemTile(int col, int row) const override { + return row == 1 || row == 2; + } + + bool isShimNOCTile(int col, int row) const override { + return row == 0 && nocColumns.contains(col); + } + + bool isShimPLTile(int col, int row) const override { + return row == 0 && !nocColumns.contains(col); + } + + bool isShimNOCorPLTile(int col, int row) const override { + return isShimNOCTile(col, row) || isShimPLTile(col, row); + } + + uint32_t getNumMemTileRows() const override { return 2; } +}; + +class BaseNPUTargetModel : public AIE2TargetModel { +public: + BaseNPUTargetModel() = default; + + int rows() const override { + return 6; /* 1 Shim row, 1 memtile row, and 4 Core rows. */ + } + + bool isCoreTile(int col, int row) const override { return row > 1; } + bool isMemTile(int col, int row) const override { return row == 1; } + + bool isShimPLTile(int col, int row) const override { + return false; // No PL + } + + bool isShimNOCorPLTile(int col, int row) const override { + return isShimNOCTile(col, row) || isShimPLTile(col, row); + } + + uint32_t getNumMemTileRows() const override { return 1; } + + // Return true if the device model is virtualized. This is used + // during CDO code generation to configure aie-rt properly. + virtual bool isVirtualized() const = 0; + + virtual bool isNPU() const override { return true; } +}; + +// The full Phoenix NPU +class NPUTargetModel : public BaseNPUTargetModel { +public: + NPUTargetModel() = default; + + int columns() const override { return 5; } + + bool isShimNOCTile(int col, int row) const override { + return row == 0 && col > 0; + } + + bool isShimPLTile(int col, int row) const override { + // This isn't useful because it's not connected to anything. + return row == 0 && col == 0; + } + + bool isVirtualized() const override { return false; } +}; + +// A sub-portion of the NPU +class VirtualizedNPUTargetModel : public BaseNPUTargetModel { + int cols; + +public: + VirtualizedNPUTargetModel(int _cols) : cols(_cols) {} + + uint32_t getAddressGenGranularity() const override { return 32; } + + int columns() const override { return cols; } + + bool isShimNOCTile(int col, int row) const override { return row == 0; } + + bool isVirtualized() const override { return true; } +}; + +} // namespace xilinx::AIE + +namespace llvm { +template <> +struct DenseMapInfo { + using FirstInfo = DenseMapInfo; + using SecondInfo = DenseMapInfo; + + static xilinx::AIE::TileID getEmptyKey() { + return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; + } + + static xilinx::AIE::TileID getTombstoneKey() { + return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; + } + + static unsigned getHashValue(const xilinx::AIE::TileID &t) { + return detail::combineHashValue(FirstInfo::getHashValue(t.col), + SecondInfo::getHashValue(t.row)); + } + + static bool isEqual(const xilinx::AIE::TileID &lhs, + const xilinx::AIE::TileID &rhs) { + return lhs == rhs; + } +}; +} // namespace llvm + +template <> +struct std::hash { + std::size_t operator()(const xilinx::AIE::TileID &s) const noexcept { + std::size_t h1 = std::hash{}(s.col); + std::size_t h2 = std::hash{}(s.row); + return h1 ^ (h2 << 1); + } +}; + +#endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td new file mode 100644 index 000000000..aa2dc5388 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td @@ -0,0 +1,41 @@ +//===- AIETypes.td -----------------------------------------*- tablegen -*-===// +// +// 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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIE_TYPES +#define AIE_TYPES + +include "AIE.td" +include "AIEAttrs.td" + +include "mlir/IR/AttrTypeBase.td" + +def AIE_ObjectFifoType : + DialectType($_self)">, + "AIE objectFifo type">; + +def AIE_ObjectFifoSubviewType : + DialectType($_self)">, + "AIE ObjectFifoSubview type">; + +def AIE_Type : AnyTypeOf<[AIE_ObjectFifoType, AIE_ObjectFifoSubviewType]>; + +def AIE_ObjectFifo_Depth : AnyAttrOf<[ConfinedAttr]>, ArrayAttr]>; + +def AnyScalarOrTensor : TypeConstraint, + "scalar-or-tensor">; + +def AnyScalar : TypeConstraint, + "scalar">; + +#endif // AIE_TYPES \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEX.td b/compiler/plugins/target/AMD-AIE/aie/AIEX.td new file mode 100644 index 000000000..41892b615 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEX.td @@ -0,0 +1,816 @@ +//===- AIE.td ----------------------------------------------*- tablegen -*-===// +// +// 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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIEX_OPS +#define AIEX_OPS + +include "AIEAttrs.td" +include "AIEInterfaces.td" + +include "mlir/IR/OpBase.td" +include "mlir/IR/AttrTypeBase.td" +include "mlir/IR/EnumAttr.td" +include "mlir/IR/SymbolInterfaces.td" +include "mlir/Interfaces/CallInterfaces.td" +include "mlir/Interfaces/SideEffectInterfaces.td" +include "mlir/IR/CommonAttrConstraints.td" + +def AIEX_Dialect : Dialect { + let name = "aiex"; + let cppNamespace = "::xilinx::AIEX"; + let description = [{ + + This is a dialect for experimental work related to AIEngine processors. + The expectation is that new ideas can be developed here before migration + to the more mature AIE dialect. + + }]; +} + + +class AIEX_Op traits = []> : + Op; + + +def AIE_GetTileOp: AIEX_Op<"getTile", []>, Results<(outs Index:$result)> { + let arguments = ( + ins Index:$col, + Index:$row + ); + + let summary = "Get a reference to an AIE tile"; + let description = [{ + Return a reference to an AIE tile, given the column and the row of the tile. + }]; + let assemblyFormat = [{ `(` $col `,` $row `)` attr-dict }]; +} + +def AIE_ConnectionOp: AIEX_Op<"connection", []> { + let arguments = ( + ins Index:$source, + WireBundle:$sourceBundle, + I32Attr:$sourceChannel, + Index:$dest, + WireBundle:$destBundle, + I32Attr:$destChannel + ); + let summary = "A logical circuit-switched connection between cores"; + let description = [{ + The "aie.connection" operation represents a circuit switched connection between two endpoints, usually + "aie.core" operations. During routing, this is replaced by "aie.connect" operations which represent + the programmed connections inside a switchbox, along with "aie.wire" operations which represent + physical connections between switchboxes and other components. Note that while "aie.flow" operations + can express partial routes between tiles, this is not possible with "aie.connection" operations. + + Example: + %22 = aie.tile(2, 2) + %c22 = aie.core(%22) + %11 = aie.tile(1, 1) + %c11 = aie.core(%11) + aie.flow(%c22, "Core" : 0, %c11, "Core" : 1) + + }]; + let assemblyFormat = [{ + `(` $source `,` $sourceBundle `:` $sourceChannel `,` $dest `,` $destBundle `:` $destChannel `)` attr-dict + }]; + let extraClassDeclaration = [{ + int sourceIndex() { return getSourceChannel(); } + int destIndex() { return getDestChannel(); } + }]; +} + +def AIE_MulticastOp: AIEX_Op<"multicast", [SingleBlockImplicitTerminator<"AIE::EndOp">]> { + let arguments = ( + ins Index:$tile, + WireBundle:$bundle, + I32Attr:$channel + ); + let regions = (region AnyRegion:$ports); + let summary = "An abstraction of multicast"; + let description = [{ + An abstraction of broadcast. During place and + route, it will be replaced by multiple flows. + + Example: + ``` + %70 = AIE.tile(7, 0) + %73 = AIE.tile(7, 3) + %74 = AIE.tile(7, 4) + %63 = AIE.tile(6, 3) + %64 = AIE.tile(6, 4) + aiex.multicast(%70, "DMA" : 0){ + aiex.multi_dest<%73, "DMA" : 0> + aiex.multi_dest<%74, "DMA" : 0> + aiex.multi_dest<%63, "DMA" : 0> + aiex.multi_dest<%64, "DMA" : 0> + } + ``` + }]; + let assemblyFormat = [{ `(` $tile `,` $bundle `:` $channel `)` regions attr-dict }]; + let hasVerifier = 1; + let extraClassDeclaration = [{ + int channelIndex() { return getChannel(); } + AIE::Port port() { return {getBundle(), channelIndex()}; } + }]; +} + +def AIE_MultiDestOp: AIEX_Op<"multi_dest", [HasParent<"MulticastOp">]> { + let arguments = ( + ins Index:$tile, + WireBundle:$bundle, + I32Attr:$channel + ); + let summary = "A destination port of multicast flow"; + let description = [{ + An object representing the destination of a multicast flow. This must exist + within an [aiex.multicast] operation. There can be multiple destinations within an + aiex.multicast Op. + + See [aiex.multicast]for an example. + }]; + let assemblyFormat = [{ + `<` $tile `,` $bundle `:` $channel `>` attr-dict + }]; + let extraClassDeclaration = [{ + int channelIndex() { return getChannel(); } + AIE::Port port() { return {getBundle(), channelIndex()}; } + }]; +} + +def AIE_BroadcastPacketOp: AIEX_Op<"broadcast_packet", [SingleBlockImplicitTerminator<"AIE::EndOp">]> { + let arguments = ( + ins Index:$tile, + WireBundle:$bundle, + I32Attr:$channel + ); + let regions = (region AnyRegion:$ports); + let summary = "Combination of broadcast and packet-switch"; + let description = [{ + An abstraction of broadcast and packet-switched flow. During place and + route, it will be replaced by packet-switched flow and further replaced + by MasterSets and PacketRules inside switchboxes. + + Example: + ``` + %70 = AIE.tile(7, 0) + %73 = AIE.tile(7, 3) + %74 = AIE.tile(7, 4) + %63 = AIE.tile(6, 3) + %64 = AIE.tile(6, 4) + AIE.broadcast_packet(%70, "DMA" : 0){ + AIE.bp_id(0x0){ + AIE.bp_dest<%73, "DMA" : 0> + AIE.bp_dest<%63, "DMA" : 0> + } + AIE.bp_id(0x1){ + AIE.bp_dest<%74, "DMA" : 0> + AIE.bp_dest<%64, "DMA" : 0> + } + } + ``` + }]; + let assemblyFormat = [{ `(` $tile `,` $bundle `:` $channel `)` regions attr-dict }]; + let hasVerifier = 1; + let extraClassDeclaration = [{ + int channelIndex() { return getChannel(); } + AIE::Port port() { return {getBundle(), channelIndex()}; } + }]; +} + +def AIE_BPIDOp: AIEX_Op<"bp_id", [SingleBlockImplicitTerminator<"AIE::EndOp">]> { + let arguments = (ins I8Attr:$ID); + let regions = (region AnyRegion:$ports); + let summary = "A set of packets that share the same ID"; + let description = [{ + A set of destination packets that share the same source and ID. This must exist + within an [AIE.broadcast_packet] operation. + See [AIE.broadcast_packet]for an example. + }]; + let assemblyFormat = [{ `(` $ID `)` regions attr-dict }]; + let extraClassDeclaration = [{ + int IDInt() { return getID(); } + }]; +} + +def AIE_BPDestOp: AIEX_Op<"bp_dest", [HasParent<"BPIDOp">]> { + let arguments = ( + ins Index:$tile, + WireBundle:$bundle, + I32Attr:$channel + ); + let summary = "A destination port"; + let description = [{ + An object representing the destination of a Broad Packet. This must exist + within an [AIE.bp_id] operation. + See [AIE.broadcast_packet] for an example. + }]; + let assemblyFormat = [{ + `<` $tile `,` $bundle `:` $channel `>` attr-dict + }]; + let extraClassDeclaration = [{ + int channelIndex() { return getChannel(); } + AIE::Port port() { return {getBundle(), channelIndex()}; } + }]; +} + +def AIE_TokenOp: AIEX_Op<"token", [Symbol]> { + let summary = "Declare a token (a logical lock)"; + let description = [{ + This operation creates a logical lock. We use Symbol so that it can be referenced globally. + Unlike phsical locks, logical locks are unlimited, and we can specify any integer value + associated with a lock. The logical lock is used to manually specify the dependence of tasks, or + core executions. + + The operation can also be generated automatically if the Dependence Analysis can be leveraged. + + Example: + AIE.token(0) {sym_name = "token0"} // Declare token0 with initial value of 0 + + ... + + AIE.useToken @token0("Acquire", 0) // acquire token0 if its value is 0 + + ... + + AIE.useToken @token0("Release", 5) // release token0 and set its value to 5 + + }]; + let arguments = (ins I32Attr:$value); + let assemblyFormat = [{ `(` $value `)` attr-dict }]; + let extraClassDeclaration = [{ + int getTokenValue() { return getValue(); } + }]; +} + +def AIE_UseTokenOp: AIEX_Op<"useToken", []> { + let summary = "acquire/release a logical lock"; + let description = [{ + This operation uses token (logical lock). A logical lock can be acquired or released with a value. + Similar to UseLockOp, this operation can be understood as "blocking" op. + }]; + let arguments = ( + ins FlatSymbolRefAttr:$tokenName, + I32Attr:$value, + LockAction:$action + ); + let assemblyFormat = [{ $tokenName `(` $action `,` $value `)` attr-dict }]; + let hasVerifier = 1; + let extraClassDeclaration = [{ + bool acquire() { return (getAction() == AIE::LockAction::Acquire); } + bool release() { return (getAction() == AIE::LockAction::Release); } + int getTokenValue() { return getValue(); } + }]; +} + +def AIE_MemcpyOp: AIEX_Op<"memcpy", []> { + let summary = "A memcpy op"; + let description = [{ + This operation defines a logical data transfer of a buffer from a source tile to another buffer + from a destination tile. + + This operation should be lowered to Mem ops with DMA setup and Flow ops for routing data from + the source tile to the dest. tile. + }]; + let arguments = ( + ins FlatSymbolRefAttr:$tokenName, + I32Attr:$acqValue, + I32Attr:$relValue, + Index:$srcTile, + AnyMemRef:$srcBuf, + I32Attr:$srcOffset, + I32Attr:$srcLen, + Index:$dstTile, + AnyMemRef:$dstBuf, + I32Attr:$dstOffset, + I32Attr:$dstLen + ); + let assemblyFormat = [{ + $tokenName `(` $acqValue `,` $relValue `)` `(` + $srcTile `:` `<` $srcBuf `,` $srcOffset `,` $srcLen `>` `,` + $dstTile `:` `<` $dstBuf `,` $dstOffset `,` $dstLen `>` `)` + attr-dict `:` `(` type($srcBuf) `,` type($dstBuf) `)` + }]; + let extraClassDeclaration = [{ + int getAcquireTokenValue() { return getAcqValue(); } + int getReleaseTokenValue() { return getRelValue(); } + int getSrcOffsetValue() { return getSrcOffset(); } + int getDstOffsetValue() { return getDstOffset(); } + int getSrcLenValue() { return getSrcLen(); } + int getDstLenValue() { return getDstLen(); } + }]; +} + + + + +/// Experimental Herd operations +def AIE_HerdOp: AIEX_Op<"herd", []>, Results<(outs Index)> { + let summary = "Declare a herd which is a bundle of core organized in a rectangular shape"; + let description = [{ + This operation creates a group of AIE tiles in 2D shape. + + Example: + %herd0 = AIE.herd[1][1] // a single AIE tile. location unknown + %herd1 = AIE.herd[4][1] // a row of four-AIE tile + + The operation can be used in replacement of a TileOp -- in case we want to select a group of + hardware entities (cores, mems, switchboxes) instead of individual entity, and we don't want to + specify their locations just yet. This can be useful if we want to generate parameterizable + code (the column and row values are parameterized). + + Example: + + %herd = AIE.herd[2][2] // a herd of 2x2 AIE tiles + + AIE.core(%herd) { + // all the cores belong to this herd runs the same code + } + }]; + let arguments = ( + ins I32Attr:$width, + I32Attr:$height + ); + let extraClassDeclaration = [{ + int getHerdWidth() { return getWidth(); } + int getHerdHeight() { return getHeight(); } + int getNumAIETiles() { return getHerdWidth() * getHerdHeight(); } + mlir::StringAttr name() { + if (auto attr = getOperation()->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())) + return attr; + emitOpError("does not have '") + << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; + llvm::report_fatal_error("couldn't get name"); + } + }]; + let assemblyFormat = [{ `[` $width `]` `[` $height `]` attr-dict }]; + let builders = [ + OpBuilder<(ins "int":$width, "int":$height), + [{ + build($_builder, $_state, $_builder.getIndexType(), + $_builder.getI32IntegerAttr(width), + $_builder.getI32IntegerAttr(height)); + }]> + ]; +} + +def AIE_PlaceOp: AIEX_Op<"place", []> { + let summary = "A place operation that specifies the relative placement (XY) of one herd to another"; + let description = [{ + A place operation that specifies the relative placement (XY) of one herd to another. + }]; + let arguments = ( + ins Index:$sourceHerd, + Index:$destHerd, + I32Attr:$distX, + I32Attr:$distY + ); + let assemblyFormat = [{ `(` $sourceHerd `,` $destHerd `,` $distX `,` $distY `)` attr-dict }]; + let extraClassDeclaration = [{ + int getDistXValue() { return getDistX(); } + int getDistYValue() { return getDistY(); } + }]; +} + +def AIE_RouteOp: AIEX_Op<"route", []> { + let summary = "A route operation that routes one herd to another"; + let description = [{ + A route operation that routes one herd to another. + }]; + let arguments = ( + ins Index:$sourceHerds, + WireBundle:$sourceBundle, + I32Attr:$sourceChannel, + Index:$destHerds, + WireBundle:$destBundle, + I32Attr:$destChannel + ); + let assemblyFormat = [{ + `(` `<` $sourceHerds `,` $sourceBundle `:` $sourceChannel `>` `,` + `<` $destHerds `,` $destBundle `:` $destChannel `>` `)` attr-dict + }]; + let extraClassDeclaration = [{ + int getSourceChannelValue() { return getSourceChannel(); } + int getDestChannelValue() { return getDestChannel(); } + }]; +} + +def AIE_IterOp: AIEX_Op<"iter", []>, Results<(outs Index)> { + let summary = "An iter operation"; + let description = [{ + This operation generates index values that can be used with the SelectOp to select a group of tiles + from a herd. + + Example: + %iter0 = AIE.iter(0, 15, 1) // 0, 1, 2, ... , 15 + %iter1 = AIE.iter(2, 8, 2) // 2, 4, 6 + }]; + let arguments = ( + ins I32Attr:$start, + I32Attr:$end, + I32Attr:$stride + ); + let assemblyFormat = [{ `(` $start `,` $end `,` $stride `)` attr-dict }]; + let extraClassDeclaration = [{ + int getStartValue() { return getStart(); } + int getEndValue() { return getEnd(); } + int getStrideValue() { return getStride(); } + }]; + let builders = [ + OpBuilder<(ins "int":$start, "int":$end, "int":$stride), [{ + build($_builder, $_state, $_builder.getIndexType(), + $_builder.getI32IntegerAttr(start), + $_builder.getI32IntegerAttr(end), + $_builder.getI32IntegerAttr(stride)); + }]> + ]; +} + +def AIE_SelectOp: AIEX_Op<"select", []>, Results<(outs Index)> { + let summary = "A select operation"; + let description = [{ + This operation selects a group of tiles based on the selected indices. + + Example: + + %herd = AIE.herd[4][4] // a herd of 4x4 tiles + + %ix = AIE.iter(0, 4, 1) // 0, 1, 2, 3 + %iy = AIE.iter(0, 1, 1) // 0 + + %sub_herd = AIE.select(%herd, %ix, %iy) + + The SelectOp in the above example will select the tiles %herd[0][0], %herd[1][0], + %herd[2][0], %herd[3][0] (the first column of the herd). + }]; + let arguments = ( + ins Index:$startHerd, + Index:$iterX, + Index:$iterY + ); + let assemblyFormat = [{ `(` $startHerd `,` $iterX `,` $iterY `)` attr-dict }]; + let builders = [ + OpBuilder<(ins "mlir::Value":$startHerd, "mlir::Value":$iterX, "mlir::Value":$iterY), [{ + build($_builder, $_state, $_builder.getIndexType(), + startHerd, iterX, iterY); + }]> + ]; +} + +def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator, HasParent<"AIE::DeviceOp">]> { + let summary = "Program the configuration co-processor of the AI Engine array"; + let description = [{ + Instructions in this operation allow for runtime (re-)configuration of the AI Engine array, such as configuring data movement buffer descriptors. + These instructions will execute on the configuration co-processor of the AI Engine array. + + Typically, these instructions include configuring the data transfers between host and AIE array on the shims. + The input arguments are arguments passed in from the host at kernel invocation time. This may include buffers on the host. + }]; + let arguments = ( + ins OptionalAttr:$sym_name + ); + let regions = (region + AnyRegion:$body + ); + let hasCustomAssemblyFormat = 1; + let hasVerifier = 1; +} + +def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ + AttrSizedOperandSegments, + MyOffsetSizeAndStrideOpInterface + ]> { + let summary = "half DMA operator"; + + let description = [{ + An n-dimensional half DMA operator. + + Programs a DMA on coordinates (`x`, `y`) to access a memory `memref` with an access + pattern specified by `offsets`, `sizes` and `strides` or `static_offsets`, `static_sizes` + and `static_strides`. The operator references the target channel through the `metadata` + symbol and specifies a descriptor `id` to be used, which will become the `bd_id` to be used + when lowered further. The `issue_token` attribute specifies whether the execution of this + operation should issue a token which can be received and read for synchronization purposes. + This `issue_token` attribute is set to `false` by default for `MM2S` for backward compatibility + and **is always set to true for** `S2MM` channels. + + #### `metadata` -- Specifying Tile, Channel, Direction and Linking a `dma_memcpy_nd` to its Other Half + + The `metadata` attribute must point to a symbol referencing a + [`aie.shim_dma_allocation` operation](AIE.html#aiedma_bd-xilinxaiedmabdop). + The tile coordinates of the DMA to configure, the channel number and the direction (`MM2S` or `S2MM`) are taken from this operation. + + To connect the DMA to its other half (i.e. a `MM2S` DMA to its receiving end and a `S2MM` to the sending end), + the user must configure a flow (`aie.flow`) between the tile and channel referenced in the `aie.shim_dma_allocation` and the corresponding other end. + + When using ObjectFIFOs, the `aie.shim_dma_allocation` operations and the `aie.flows` are generated automatically. + The symbol of the `aie.objectfifo` (create) operation can be used directly in `metadata` in this case. + + #### Notes on Synchronization and Reusing Buffer Descriptor IDs + + When the `dma_memcpy_nd` operation executes, it immediately reprograms the buffer descriptor with ID `bd_id` on tile (`x`, `y`), even if that buffer descriptor is currently executing. + Without proper synchronization, this inevitably leads to nondeterministic results. + + Programming a buffer descriptor that is not currently executing is harmless. + Thus, the first `dma_memcpy_nd` call for each `bd_id` requires no synchronization. + + However, if you wish to later re-use a `bd_id` on the same tile, you must wait for the previous buffer descriptor to complete. + The `sync` or `dma_wait` operations can be used for this. + + `sync` blocks until it receives a _task completion token_ (TCT). + To properly synchronize, you must thus configure your BD to issue a TCT using the `issue_token` attribute, then wait on that token before reusing the BD. + + `dma_wait` is a convenience operation that lowers to the corresponding `sync` operation for the refrenced symbol. + + Note that if you have multiple concurrently running BDs and you can reason one BD will always complete after all others, it is not strictly necessary to issue and wait on the TC token for every BD. + For example, if you have input and output BDs on the shim, and you know the cores will only push output onto the output BD after the input BDs have completed, it may be sufficient to synchronize only on the output BD before reusing input BDs. + + #### Data Layout Transformations + + The `sizes` and `strides` attributes describe a data layout transformation to be performed by the DMA. + These transformations are described in more depth in the documentation for the + [`aie.dma_bd` operation](AIE.html#aiedma_bd-xilinxaiedmabdop). + Note that the syntax here differs from that of the `dma_bd` operation: + offsets and strides are given as separate arrays instead of tuples. + + The `offsets` array is used to calculate a static offset into the memref. + Each offset in the array is understood in relation to the shape of the memref; + the lowest-dimension `offset` is a direct offset in units of memref element type, and the higher dimensions are multiplied by the size of the memref in those dimensions. + Note that this is for convenience of the user only. + The hardware only supports a single static offset, and this offset is calculated at compile time. + Thus, all offsets can be equivalently expressed with the lowest dimension only. + + }]; + + let arguments = ( + ins I64Attr:$x, + I64Attr:$y, + AnyMemRef:$memref, + // NOTE: these are in reverse order: offset3, offset2, ... + Variadic:$offsets, + Variadic:$sizes, + Variadic:$strides, + ConfinedAttr]>:$static_offsets, + ConfinedAttr]>:$static_sizes, + ConfinedAttr]>:$static_strides, + FlatSymbolRefAttr:$metadata, + I64Attr:$id, + DefaultValuedOptionalAttr:$issue_token + ); + + let assemblyFormat = [{ + `(` $x `,` $y `,` $memref `` + custom($offsets, $static_offsets) `` + custom($sizes, $static_sizes) `` + custom($strides, $static_strides) `)` + attr-dict `:` type($memref) + }]; + + let extraClassDeclaration = [{ + static unsigned getOffsetSizeAndStrideStartOperandIndex(); + static std::array getArrayAttrMaxRanks(); + + /* Returns the provided multi-dimensional data transfer strides in units of + address granularity. In the IR, we express strides in units of element + data type, but the hardware requires it in units of address granularity. + Address granularity currently is 4 bytes for all hardware. + + The returned stride[0] is the second-lowest dimension stride, i.e. + stride 1. The lowest stride is currently implicitly one, but this is not + a hardware requirement and could be changed in the future. */ + llvm::SmallVector getStridesInAddressGranularity(); + + /* Returns the multi-dimensional data transfer sizes in units of address + granularity. These sizes are expressed in units of element data type in + the IR, but the hardware requires them to be in units of address + granularity. Address granularity currently is 4 bytes for all hardware. + + The returned size[0] is the lowest dimension size. In the IR, the sizes + are given in reverse order. For example, specifying sizes in IR as + [1, 2, 3, 4] would result in this function returning [4, 3, 2, 1]. + */ + llvm::SmallVector getSizesInAddressGranularity(); + + /* Returns the data transfer offset in bytes, i.e. the first N bytes of the + target buffer will be skipped. In the IR, offsets are expressed in units + of memref element data type size. */ + int64_t getOffsetInBytes(); + }]; + + let extraClassDefinition = [{ + unsigned $cppClass::getOffsetSizeAndStrideStartOperandIndex() { return 1; } + std::array $cppClass::getArrayAttrMaxRanks() { return {4, 4, 4}; } + }]; + + let hasVerifier = 1; +} + +def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { + let summary = "Blocking operation to wait for a DMA to complete execution."; + let description = [{ + The NpuDmaWaitOp blocks until the DMA referenced through `symbol` completes execution + and issues a task-complete-token (TCT). + + `symbol` is a reference to a `aie.shim_dma_allocation`, which contains information about the column, channel and channel direction on which to wait for a TCT. + The `aie.shim_dma_allocation` may be generated from an ObjectFIFO, in which case you can directly pass the ObjectFIFO symbol refrence. + `npu.dma_wait` will be lowered to the corresponding `npu.sync` operation using the information from `symbol`. + + Example: + ```mlir + ... + aie.objectfifo @out0(%tile_0_1, {% raw %}{%tile_0_0}{% endraw %}, 4 : i32) : !aie.objectfifo> + ... + aiex.npu.dma_memcpy_nd(0, 0, %arg2[1, 1, 0, 0][1, 1, 32, 32][1, 1, 64, 1]) {id = 0 : i64, issue_token = true, metadata = @out0} : memref<32x64xi32> + ... + aiex.npu.dma_wait { symbol = @out0 } + ``` + Here, we have an objectfifo with symbol name `out0`, which is then referenced in the + `npu.dma_memcpy_nd` operation as the target for the respective DMA operation. Afterwards, + an `npu.dma_wait` operation references the same symbol to block until the respective DMA + has executed all of its tasks. + }]; + let arguments = ( + ins FlatSymbolRefAttr:$symbol + ); + let assemblyFormat = [{ + attr-dict + }]; + let hasVerifier = 1; +} + +// Write RTP +def AIE_NpuWriteRTPOp: AIEX_Op<"npu.rtp_write", []> { + let summary = "rtp write operator"; + let arguments = ( + ins FlatSymbolRefAttr:$buffer, + UI32Attr:$index, + I32Attr:$value + ); + let results = (outs ); + let assemblyFormat = [{ `(` $buffer `,` $index `,` $value `)` attr-dict + }]; + let description = [{ + rtp write operator + }]; +} + +// Push BD to Queue +def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue", []> { + let summary = "bd queue push operator"; + let arguments = ( + ins I32Attr:$column, + I32Attr:$row, + DMAChannelDir:$direction, + I32Attr:$channel, + BoolAttr:$issue_token, + I32Attr:$repeat_count, + I32Attr:$bd_id + ); + let results = (outs ); + let assemblyFormat = [{ + `(` $column `,` $row `,` $direction `:` $channel `)` attr-dict + }]; + let hasVerifier = 1; + let description = [{ + bd queue push operator + }]; +} + +// WRITE32 +def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> { + let summary = "write32 operator"; + let arguments = ( + ins UI32Attr:$address, + UI32Attr:$value, + OptionalAttr:$buffer, + OptionalAttr:$column, + OptionalAttr:$row + ); + let results = (outs ); + let assemblyFormat = [{ + attr-dict + }]; + let description = [{ + NPU write32 operator writes a 32bit value to the AIE array. + If 'buffer' is present then 'address' is interpreted as an offset into the + aie.buffer with symbol name 'buffer'. + If 'column' and 'row' are present then 'address' is interpreted as an offset + into the memory space of aie.tile(column, row). + If 'buffer' is not present and 'column' and 'row' are not present then + 'address' is interpreted as a full 32-bit address in the AIE array. + }]; +} + +// BLOCKWRITE +def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite", []> { + let summary = "blockwrite operator"; + let arguments = ( + ins UI32Attr:$address, + AnyMemRef:$data, + OptionalAttr:$buffer, + OptionalAttr:$column, + OptionalAttr:$row + ); + let results = (outs ); + let assemblyFormat = [{ + `(` $data `)` attr-dict `:` type($data) + }]; + let description = [{ + blockwrite operator writes the data from the memref 'data' to the AIE array. + If 'buffer' is present then 'address' is interpreted as an offset into the + aie.buffer with symbol name 'buffer'. + If 'column' and 'row' are present then 'address' is interpreted as an offset + into the memory space of aie.tile(column, row). + If 'buffer' is not present and 'column' and 'row' are not present then + 'address' is interpreted as a full 32-bit address in the AIE array. + }]; +} + +// OP_SYNC +def AIE_NpuSyncOp: AIEX_Op<"npu.sync", []> { + let summary = "sync operator"; + let arguments = ( + ins I32Attr:$column, + I32Attr:$row, + I32Attr:$direction, + I32Attr:$channel, + I32Attr:$column_num, + I32Attr:$row_num + ); + let results = (outs ); + let assemblyFormat = [{ + attr-dict + }]; + let description = [{ + The sync operation blocks execution of the instruction stream until a task-complete token (TCT) is received on `column`, `row`, channel `channel`, direction `direction` (where `0` is `S2MM` and `1` is `MM2S`). + + #### Troubleshooting + + If this operation appears to deadlock, ensure that at least one buffer descriptor is configured to issue a TCT on the channel you expect. + By default, `dma_memcpy_nd` operations only issue tokens for `S2MM` channels, and `issue_token` must be set to `true` to issue tokens for `MM2S` channels. + }]; +} + +// XAIE_IO_CUSTOM_OP_BEGIN + 1 (address patch) +def AIE_NpuAddressPatchOp: AIEX_Op<"npu.address_patch", []> { + let summary = "address patch operator"; + let arguments = ( + ins UI32Attr:$addr, + I32Attr:$arg_idx, + I32Attr:$arg_plus + ); + let results = (outs ); + let assemblyFormat = [{ + attr-dict + }]; + let description = [{ + address patch operator + }]; +} + +// NPU Bd Write operation +def AIE_NpuWriteBdOp: AIEX_Op<"npu.writebd", []> { + let summary = "dma operator"; + let arguments = ( + ins I32Attr:$column, + I32Attr:$bd_id, + I32Attr:$buffer_length, + I32Attr:$buffer_offset, + I32Attr:$enable_packet, + I32Attr:$out_of_order_id, + I32Attr:$packet_id, + I32Attr:$packet_type, + I32Attr:$d0_size, + I32Attr:$d0_stride, + I32Attr:$d1_size, + I32Attr:$d1_stride, + I32Attr:$d2_stride, + I32Attr:$iteration_current, + I32Attr:$iteration_size, + I32Attr:$iteration_stride, + I32Attr:$next_bd, + I32Attr:$row, + I32Attr:$use_next_bd, + I32Attr:$valid_bd, + I32Attr:$lock_rel_val, + I32Attr:$lock_rel_id, + I32Attr:$lock_acq_enable, + I32Attr:$lock_acq_val, + I32Attr:$lock_acq_id + ); + let results = (outs ); + let assemblyFormat = [{ attr-dict }]; + let hasVerifier = 1; + let description = [{ + writebd operator + }]; +} + +#endif // AIEX_OPS \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp new file mode 100644 index 000000000..2b1cbf9f4 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp @@ -0,0 +1,359 @@ +//===- AIEXDialect.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 +// +// (c) Copyright 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#include "AIEXDialect.h" + +#include "mlir/Dialect/Func/IR/FuncOps.h" +#include "mlir/Interfaces/FoldInterfaces.h" +#include "mlir/Transforms/InliningUtils.h" + +using namespace mlir; +using namespace xilinx; + +#include "aie/AIEXDialect.cpp.inc" + +namespace xilinx::AIEX { + +// FIXME: use Tablegen'd dialect class +void AIEXDialect::initialize() { + addOperations< +#define GET_OP_LIST +#include "aie/AIEX.cpp.inc" + >(); +} + +} // namespace xilinx::AIEX + +#define GET_OP_CLASSES +#include "aie/AIEX.cpp.inc" + +LogicalResult AIEX::UseTokenOp::verify() { + auto *parentOp = (*this)->getParentOp(); + if (isa(parentOp) || isa(parentOp) || + isa(parentOp) || isa(parentOp)) + return success(); + return failure(); +} + +LogicalResult AIEX::MulticastOp::verify() { + Region &body = getPorts(); + assert(getOperation()->getNumRegions()); + assert(!body.empty()); + for (auto &ops : body.front()) + if (!isa(ops)) + return ops.emitOpError("cannot be contained in a Multicast op"); + + return success(); +} + +LogicalResult AIEX::BroadcastPacketOp::verify() { + Region &body = getPorts(); + assert(getOperation()->getNumRegions()); + assert(!body.empty()); + for (auto &ops : body.front()) + if (!isa(ops)) + return ops.emitOpError("cannot be contained in a BroadcastPacket op"); + + return success(); +} + +llvm::SmallVector +AIEX::NpuDmaMemcpyNdOp::getStridesInAddressGranularity() { + const auto &targetModel = AIE::getTargetModel(*this); + MemRefType buffer = getMemref().getType(); + auto elemWidth = buffer.getElementTypeBitWidth(); + auto addressGranularity = targetModel.getAddressGenGranularity(); + llvm::SmallVector strides = + llvm::map_to_vector(llvm::reverse(getMixedStrides()), [](OpFoldResult s) { + return getConstantIntValue(s).value(); + }); + if (!strides.empty()) { + for (int i = 0; i < 4; i++) { + strides[i] = (strides[i] * elemWidth) / addressGranularity; + } + } + return strides; +} + +llvm::SmallVector +AIEX::NpuDmaMemcpyNdOp::getSizesInAddressGranularity() { + const auto &targetModel = AIE::getTargetModel(*this); + MemRefType buffer = getMemref().getType(); + auto elemWidth = buffer.getElementTypeBitWidth(); + auto addressGranularity = targetModel.getAddressGenGranularity(); + llvm::SmallVector sizes = + llvm::map_to_vector(llvm::reverse(getMixedSizes()), [](OpFoldResult s) { + return getConstantIntValue(s).value(); + }); + if (!sizes.empty()) { + sizes[0] = (sizes[0] * elemWidth) / addressGranularity; + } + return sizes; +} + +/* Calculates the offset value to be written to the + */ +int64_t AIEX::NpuDmaMemcpyNdOp::getOffsetInBytes() { + llvm::SmallVector offsets = + llvm::map_to_vector(llvm::reverse(getMixedOffsets()), [](OpFoldResult s) { + return getConstantIntValue(s).value(); + }); + size_t stride = 1; + size_t offset = 0; + MemRefType my_memref = getMemref().getType(); + auto shape = my_memref.getShape(); + size_t R = shape.size(); + size_t el_bit_width = my_memref.getElementTypeBitWidth(); + assert(el_bit_width % 8 == 0 && + "Expected Memref element bitwidth to be multiple of 8."); + size_t S = el_bit_width / 8; + for (size_t i = 0; i < R; i++) { + offset += offsets[i] * stride * S; + stride *= shape[R - i - 1]; + } + return offset; +} + +LogicalResult AIEX::NpuDmaMemcpyNdOp::verify() { + MemRefType buffer = getMemref().getType(); + const auto &targetModel = AIE::getTargetModel(*this); + auto addressGranularity = targetModel.getAddressGenGranularity(); + auto elemWidth = buffer.getElementTypeBitWidth(); + + if (buffer.getElementTypeBitWidth() > addressGranularity) { + return emitOpError("Maximum element bit width allowed is ") + << addressGranularity << "bits. "; + } else if ((buffer.getNumElements() * buffer.getElementTypeBitWidth()) < + addressGranularity) { + return emitOpError("Minimum data transfer size required is ") + << addressGranularity << "bits. "; + } + if (!llvm::all_of(getMixedStrides(), [](OpFoldResult s) { + return getConstantIntValue(s).has_value(); + })) + return emitOpError("Only constant strides currently supported."); + if (!llvm::all_of(getMixedSizes(), [](OpFoldResult s) { + return getConstantIntValue(s).has_value(); + })) + return emitOpError("Only constant sizes currently supported."); + if (!llvm::all_of(getMixedOffsets(), [](OpFoldResult s) { + return getConstantIntValue(s).has_value(); + })) + return emitOpError("Only constant offsets currently supported."); + + llvm::SmallVector raw_strides = + llvm::map_to_vector(llvm::reverse(getMixedStrides()), [](OpFoldResult s) { + return getConstantIntValue(s).value(); + }); + llvm::SmallVector raw_sizes = + llvm::map_to_vector(llvm::reverse(getMixedSizes()), [](OpFoldResult s) { + return getConstantIntValue(s).value(); + }); + + llvm::SmallVector strides = getStridesInAddressGranularity(); + llvm::SmallVector sizes = getSizesInAddressGranularity(); + int64_t offset = getOffsetInBytes(); + + // The experimental HSA target uses this op on AIE1, skip all the AIE2 + // specific checks + if (targetModel.getTargetArch() == AIE::AIEArch::AIE1) + return success(); + + uint32_t wrap_bits = 0; + uint32_t step_bits = 0; + uint32_t iter_bits = 6; + if (targetModel.isShimNOCTile(getX(), getY())) { + step_bits = 20; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_STEPSIZE_WIDTH + wrap_bits = 10; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_WRAP_WIDTH + } else if (targetModel.isMemTile(getX(), getY())) { + step_bits = 17; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH + wrap_bits = 10; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_WRAP_WIDTH + } else if (targetModel.isCoreTile(getX(), getY())) { + step_bits = 13; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH + wrap_bits = 8; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_3_D0_WRAP_WIDTH + } else { + return emitOpError("Unsupported tile type at (" + std::to_string(getX()) + + ", " + std::to_string(getY()) + + ") Must be ShimNOC, Mem or Core."); + } + + if (sizes[3] > (1 << iter_bits)) + return emitOpError( + "Size 3 exceeds the [1:" + std::to_string(1 << iter_bits) + "] range."); + if (strides[2] && sizes[1] > (1 << wrap_bits) - 1) + return emitOpError("Size 1 exceeds the [0:" + + std::to_string((1 << wrap_bits) - 1) + "] range."); + if (strides[1] && sizes[0] > (1 << wrap_bits) - 1) + return emitOpError("Size 0 exceeds the [0:" + + std::to_string((1 << wrap_bits) - 1) + "] range."); + // strides[3] exceeding the range is ok iff the sizes[3] is one, which is + // checked below + if (strides[3] > (1 << step_bits) && sizes[3] != 1) + return emitOpError("Stride 3 exceeds the [1:" + + std::to_string(1 << step_bits) + "] range."); + if (strides[2] > (1 << step_bits)) + return emitOpError("Stride 2 exceeds the [1:" + + std::to_string(1 << step_bits) + "] range."); + if (strides[1] > (1 << step_bits)) + return emitOpError("Stride 1 exceeds the [1:" + + std::to_string(1 << step_bits) + "] range."); + + if (offset % 4 != 0) { + return emitOpError("Offset must be 4-byte-aligned."); + } + + for (int i = 0; i < 4; i++) { + // strides[0] == 1 is ok iff the tranfer size is a multiple of + // addressGranularity, which is checked below + if (i == 0 && raw_strides[i] == 1) + continue; + if (raw_strides[i] * elemWidth % addressGranularity != 0) { + std::stringstream msg; + msg << "Stride " << i << " is " << raw_strides[i] << " elements * " + << (elemWidth / 8) << " bytes = " << (raw_strides[i] * elemWidth / 8) + << " bytes, which is not divisible by " << (addressGranularity / 8) + << ". "; + return emitOpError(msg.str()); + } + } + + if (raw_sizes[0] * elemWidth % addressGranularity != 0) { + std::stringstream msg; + msg << "Transfer sizes must be multiples of " << (addressGranularity / 8) + << " bytes. " << raw_sizes[0] << " elements at " << (elemWidth / 8) + << " bytes each equal " << (raw_sizes[0] * elemWidth / 8) + << " bytes, which is not divisible by " << (addressGranularity / 8) + << ". "; + return emitOpError(msg.str()); + } + + return success(); +} + +LogicalResult AIEX::NpuDmaWaitOp::verify() { + AIE::DeviceOp dev = (*this)->getParentOfType(); + // Some passes (e.g. aie-standard-lowering) use aiex ops outside a DeviceOp, + // so we can't expect the device to always exist. + if (dev && !dev.lookupSymbol(getSymbol())) + return emitOpError("couldn't find symbol in parent device"); + return success(); +} + +LogicalResult AIEX::NpuPushQueueOp::verify() { + const auto &targetModel = AIE::getTargetModel(*this); + auto numBds = targetModel.getNumBDs(getColumn(), getRow()); + if (getBdId() > numBds) + return emitOpError("BD ID exceeds the maximum ID."); + if (getRepeatCount() > 255) + return emitOpError("Repeat count exceeds the [0:255] range."); + return success(); +} + +LogicalResult AIEX::NpuWriteBdOp::verify() { + const auto &targetModel = AIE::getTargetModel(*this); + auto numBds = targetModel.getNumBDs(getColumn(), getRow()); + if (getBdId() > numBds) + return emitOpError("BD ID exceeds the maximum ID."); + if (getD0Size() > 0x3FF) + return emitOpError("D0 Size exceeds the [0:1023] range."); + if (getD0Stride() > 0xFFFFF) + return emitOpError("D0 Stride exceeds the [0:1M-1] range."); + if (getD1Size() > 0x3FF) + return emitOpError("D1 Size exceeds the [0:1023] range."); + if (getD1Stride() > 0xFFFFF) + return emitOpError("D1 Stride exceeds the [0:1M-1] range."); + if (getD2Stride() > 0xFFFFF) + return emitOpError("D2 Stride exceeds the [0:1M-1] range."); + if (getIterationSize() > 0x3F) + return emitOpError("Iteration Size exceeds the [0:63] range."); + if (getIterationStride() > 0xFFFFF) + return emitOpError("Iteration Stride exceeds the [0:1M-1] range."); + return success(); +} + +//===----------------------------------------------------------------------===// +// RuntimeSequenceOp +//===----------------------------------------------------------------------===// + +ParseResult AIEX::RuntimeSequenceOp::parse(OpAsmParser &parser, + OperationState &result) { + + StringAttr nameAttr; + (void)parser.parseOptionalSymbolName( + nameAttr, mlir::SymbolTable::getSymbolAttrName(), result.attributes); + + SmallVector entryArgs; + + // Entry arguments, e.g. (%addr: memref<1xi32>) + ParseResult argParseResult = parser.parseCommaSeparatedList( + OpAsmParser::Delimiter::Paren, [&]() -> ParseResult { + OpAsmParser::Argument argument; + if (parser.parseArgument(argument, true, true)) { + return failure(); + } + entryArgs.push_back(argument); + return success(); + }); + if (argParseResult) { + return argParseResult; + } + + // Body + auto *body = result.addRegion(); + ParseResult bodyParseResult = parser.parseRegion(*body, entryArgs, false); + if (bodyParseResult) { + return bodyParseResult; + } + + return success(); +} + +void AIEX::RuntimeSequenceOp::print(OpAsmPrinter &printer) { + Region &body = getRegion(); + + auto nameAttr = (*this)->getAttrOfType( + mlir::SymbolTable::getSymbolAttrName()); + if (nameAttr) { + printer << ' '; + printer.printSymbolName(nameAttr); + } + + printer << '('; + for (unsigned i = 0, n = body.getNumArguments(); i < n; i++) { + if (i > 0) { + printer << ", "; + } + printer.printRegionArgument(body.getArgument(i)); + } + printer << ')'; + + printer << ' '; + printer.printRegion(body, false, true); +} + +LogicalResult AIEX::RuntimeSequenceOp::verify() { + AIE::DeviceOp device = (*this)->getParentOfType(); + if (!device) { + // this check is redudnant with the HasParent trait, but can't hurt + (*this)->emitOpError() << "must be inside AIE device operation."; + return failure(); + } + auto seq_ops = device.getOps(); + if (std::distance(seq_ops.begin(), seq_ops.end()) > 1) { + auto err = device.emitOpError() + << "Cannot have more than one runtime sequence per device."; + for (auto it = seq_ops.begin(); it != seq_ops.end(); ++it) { + AIEX::RuntimeSequenceOp seq_op = *it; + err.attachNote(seq_op.getLoc()) << "Sequence operation definition here."; + } + return failure(); + } + return success(); +} diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h new file mode 100644 index 000000000..868e62f87 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h @@ -0,0 +1,23 @@ +//===- AIEDialect.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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef MLIR_AIEX_DIALECT_H +#define MLIR_AIEX_DIALECT_H + +#include "AIEDialect.h" + +// Include dialect declarations such as parseAttributes, parseType +#include "aie/AIEXDialect.h.inc" + +// include TableGen generated Op definitions +#define GET_OP_CLASSES +#include "aie/AIEX.h.inc" + +#endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp index 4e11ba9e9..ed8946d6f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/Twine.h" #include "mlir/IR/Attributes.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp index 343fe9999..3ff8d9a83 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp @@ -8,7 +8,7 @@ #include #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "iree-amd-aie/aie_runtime/Utils/ChannelBdIdGenerator.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "mlir/Pass/Pass.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp index 162660358..6a59792fa 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp @@ -12,7 +12,7 @@ // and only assigns lock IDs to locks without an ID. #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/DenseMap.h" #include "mlir/Pass/Pass.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp index 55a58225c..bce8708dd 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h" #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h" #include "mlir/Dialect/Arith/IR/Arith.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp index ce2e1df1a..2ed54a4e3 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp @@ -10,7 +10,7 @@ #include #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "iree-amd-aie/aie_runtime/iree_aie_router.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/DenseMapInfo.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp index b17065915..2b3ab63c4 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp @@ -5,8 +5,8 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" -#include "aie/Dialect/AIEX/IR/AIEXDialect.h" +#include "AIEDialect.h" +#include "AIEXDialect.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp index 284799fa2..94ab2227c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Pass/Pass.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp index 4e26ead7b..886f3df6e 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp @@ -4,7 +4,7 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "mlir/IR/Attributes.h" #include "mlir/IR/PatternMatch.h" #include "mlir/Pass/Pass.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp index df8b964a4..5ce3c9f1c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp @@ -8,7 +8,7 @@ #include #include "Passes.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/STLExtras.h" #include "mlir/Analysis/TopologicalSortUtils.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp index bca74d507..85554418c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "Passes.h" -#include "aie/Dialect/AIEX/IR/AIEXDialect.h" +#include "AIEXDialect.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt index 101042830..f267ee086 100644 --- a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt @@ -7,16 +7,6 @@ set(IREE_PACKAGE_ROOT_DIR "${CMAKE_CURRENT_LIST_DIR}") set(IREE_PACKAGE_ROOT_PREFIX "iree::target::amd-aie::aie") -list(APPEND IREE_COMPILER_TABLEGEN_INCLUDE_DIRS - "${IREE_MLIR_AIE_SOURCE_DIR}/include") - -iree_cc_library( - NAME - defs - INCLUDES - "${IREE_MLIR_AIE_SOURCE_DIR}/include" -) - ############################################################################### # AIE Dialect ############################################################################### @@ -25,71 +15,70 @@ iree_tablegen_library( NAME AIEAttrsGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIE/IR/AIEAttrs.td" + AIEAttrs.td OUTS - -gen-attrdef-decls Dialect/AIE/IR/AIEAttrs.h.inc - -gen-attrdef-defs Dialect/AIE/IR/AIEAttrs.cpp.inc - -gen-enum-decls Dialect/AIE/IR/AIEEnums.h.inc - -gen-enum-defs Dialect/AIE/IR/AIEEnums.cpp.inc + -gen-attrdef-decls AIEAttrs.h.inc + -gen-attrdef-defs AIEAttrs.cpp.inc + -gen-enum-decls AIEEnums.h.inc + -gen-enum-defs AIEEnums.cpp.inc ) iree_tablegen_library( NAME AIEDialectGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIE/IR/AIE.td" + AIE.td OUTS - -gen-dialect-decls Dialect/AIE/IR/AIEDialect.h.inc - -gen-dialect-defs Dialect/AIE/IR/AIEDialect.cpp.inc + -gen-dialect-decls AIEDialect.h.inc + -gen-dialect-defs AIEDialect.cpp.inc ) iree_tablegen_library( NAME AIEInterfacesGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIE/IR/AIEInterfaces.td" + AIEInterfaces.td OUTS - -gen-op-interface-decls Dialect/AIE/IR/AIEInterfaces.h.inc - -gen-op-interface-defs Dialect/AIE/IR/AIEInterfaces.cpp.inc + -gen-op-interface-decls AIEInterfaces.h.inc + -gen-op-interface-defs AIEInterfaces.cpp.inc ) iree_tablegen_library( NAME AIEOpsGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIE/IR/AIEOps.td" + AIEOps.td OUTS - -gen-op-decls Dialect/AIE/IR/AIEOps.h.inc - -gen-op-defs Dialect/AIE/IR/AIEOps.cpp.inc + -gen-op-decls AIEOps.h.inc + -gen-op-defs AIEOps.cpp.inc ) iree_tablegen_library( NAME AIETypesGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIE/IR/AIETypes.td" + AIETypes.td OUTS - -gen-typedef-decls -typedefs-dialect=AIE Dialect/AIE/IR/AIETypes.h.inc - -gen-typedef-defs -typedefs-dialect=AIE Dialect/AIE/IR/AIETypes.cpp.inc + -gen-typedef-decls -typedefs-dialect=AIE AIETypes.h.inc + -gen-typedef-defs -typedefs-dialect=AIE AIETypes.cpp.inc ) iree_tablegen_library( NAME AIENormalizeAddressSpacesGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIE/Transforms/AIENormalizeAddressSpaces.td" + AIENormalizeAddressSpaces.td OUTS - -gen-rewriters Dialect/AIE/Transforms/AIENormalizeAddressSpaces.inc + -gen-rewriters AIENormalizeAddressSpaces.inc ) iree_cc_library( NAME AIEDialectIR SRCS - ${IREE_MLIR_AIE_SOURCE_DIR}/lib/Dialect/AIE/IR/AIEDialect.cpp - ${IREE_MLIR_AIE_SOURCE_DIR}/lib/Dialect/AIE/IR/AIETargetModel.cpp + AIEDialect.cpp + AIETargetModel.cpp DEPS - ::defs ::AIEAttrsGen ::AIEDialectGen ::AIEInterfacesGen @@ -117,29 +106,28 @@ iree_tablegen_library( NAME AIEXDialectGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIEX/IR/AIEX.td" + AIEX.td OUTS - -gen-dialect-decls -dialect=aiex Dialect/AIEX/IR/AIEXDialect.h.inc - -gen-dialect-defs -dialect=aiex Dialect/AIEX/IR/AIEXDialect.cpp.inc + -gen-dialect-decls -dialect=aiex AIEXDialect.h.inc + -gen-dialect-defs -dialect=aiex AIEXDialect.cpp.inc ) iree_tablegen_library( NAME AIEXOpsGen TD_FILE - "${IREE_MLIR_AIE_SOURCE_DIR}/include/aie/Dialect/AIEX/IR/AIEX.td" + AIEX.td OUTS - -gen-op-decls Dialect/AIEX/IR/AIEX.h.inc - -gen-op-defs Dialect/AIEX/IR/AIEX.cpp.inc + -gen-op-decls AIEX.h.inc + -gen-op-defs AIEX.cpp.inc ) iree_cc_library( NAME AIEXDialectIR SRCS - ${IREE_MLIR_AIE_SOURCE_DIR}/lib/Dialect/AIEX/IR/AIEXDialect.cpp + AIEXDialect.cpp DEPS - ::defs ::AIEDialectIR ::AIEXOpsGen ::AIEXDialectGen @@ -165,7 +153,6 @@ iree_cc_library( AMDAIEObjectFifoStatefulTransform.cpp AMDAIEXToStandard.cpp DEPS - ::defs iree-amd-aie::aie_runtime::iree_aie_runtime_static ::AIEDialectIR ::AIEXDialectIR diff --git a/compiler/plugins/target/AMD-AIE/aie/Passes.h b/compiler/plugins/target/AMD-AIE/aie/Passes.h index c32580e88..347c32757 100644 --- a/compiler/plugins/target/AMD-AIE/aie/Passes.h +++ b/compiler/plugins/target/AMD-AIE/aie/Passes.h @@ -7,7 +7,7 @@ #ifndef AMDAIE_PASSES_H_ #define AMDAIE_PASSES_H_ -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "AIEDialect.h" #include "mlir/Pass/Pass.h" namespace mlir::iree_compiler::AMDAIE { From f2855fca609e628bfa9095baf56e1fce383b7f7f Mon Sep 17 00:00:00 2001 From: makslevental Date: Fri, 2 Aug 2024 19:58:47 -0500 Subject: [PATCH 02/12] drop getters --- .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 270 +++--- .../plugins/target/AMD-AIE/aie/AIEDialect.h | 120 +-- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 878 ++++++------------ .../target/AMD-AIE/aie/AIETargetModel.cpp | 709 -------------- .../target/AMD-AIE/aie/AIETargetModel.h | 529 ----------- .../aie/AMDAIEObjectFifoStatefulTransform.cpp | 242 +++-- .../iree-amd-aie/PluginRegistration.cpp | 4 +- .../iree-amd-aie/Target/AIETargetDirect.h | 24 - 8 files changed, 647 insertions(+), 2129 deletions(-) delete mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp delete mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h delete mode 100644 compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETargetDirect.h diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index e0cd35f14..fab094687 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -10,6 +10,9 @@ #include "AIEDialect.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/TypeSwitch.h" #include "mlir/Dialect/Func/IR/FuncOps.h" #include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/IR/DialectImplementation.h" @@ -17,10 +20,6 @@ #include "mlir/Interfaces/FoldInterfaces.h" #include "mlir/Transforms/InliningUtils.h" -#include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallSet.h" -#include "llvm/ADT/TypeSwitch.h" - using namespace mlir; using namespace xilinx::AIE; @@ -68,13 +67,13 @@ struct AIEDialectFoldInterface : DialectFoldInterface { } }; -} // end anonymous namespace +} // end anonymous namespace namespace xilinx::AIE { LogicalResult myVerifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) { std::array maxRanks = op.getArrayAttrMaxRanks(); - if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) && // NOLINT + if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) && // NOLINT op.getMixedOffsets().size() != op.getMixedSizes().size()) return op->emitError( "expected mixed offsets rank to match mixed sizes rank (") @@ -111,10 +110,8 @@ static VirtualizedNPUTargetModel NPUmodel3col(3); static VirtualizedNPUTargetModel NPUmodel4col(4); const AIETargetModel &getTargetModel(Operation *op) { - if (auto t = dyn_cast(op)) - return t.getTargetModel(); - if (auto t = op->getParentOfType()) - return t.getTargetModel(); + if (auto t = dyn_cast(op)) return t.getTargetModel(); + if (auto t = op->getParentOfType()) return t.getTargetModel(); // For backward compatibility, return a basic device model compatible with // the VCK190 @@ -123,22 +120,22 @@ const AIETargetModel &getTargetModel(Operation *op) { const AIETargetModel &getTargetModel(AIEDevice device) { switch (device) { - case AIEDevice::xcvc1902: - return VC1902model; - case AIEDevice::xcve2302: - return VE2302model; - case AIEDevice::xcve2802: - return VE2802model; - case AIEDevice::npu1: - return NPUmodel; - case AIEDevice::npu1_1col: - return NPUmodel1col; - case AIEDevice::npu1_2col: - return NPUmodel2col; - case AIEDevice::npu1_3col: - return NPUmodel3col; - case AIEDevice::npu1_4col: - return NPUmodel4col; + case AIEDevice::xcvc1902: + return VC1902model; + case AIEDevice::xcve2302: + return VE2302model; + case AIEDevice::xcve2802: + return VE2802model; + case AIEDevice::npu1: + return NPUmodel; + case AIEDevice::npu1_1col: + return NPUmodel1col; + case AIEDevice::npu1_2col: + return NPUmodel2col; + case AIEDevice::npu1_3col: + return NPUmodel3col; + case AIEDevice::npu1_4col: + return NPUmodel4col; } return VC1902model; } @@ -148,8 +145,7 @@ const AIETargetModel &getTargetModel(AIEDevice device) { static TileElement getParentTileElement(Operation *op) { auto *parent = op->getParentOp(); while (!llvm::isa_and_nonnull(parent)) { - if (auto element = llvm::dyn_cast(parent)) - return element; + if (auto element = llvm::dyn_cast(parent)) return element; parent = parent->getParentOp(); } return llvm::dyn_cast(parent); @@ -167,7 +163,6 @@ struct UsesAreAccessable { if (llvm::isa_and_nonnull(user->getParentOp())) return success(); if (auto element = getParentTileElement(user)) { - auto tileID = element.getTileID(); if (!targetModel.isLegalMemAffinity(tileID.col, tileID.row, thisID.col, thisID.row)) @@ -216,7 +211,7 @@ struct AIEObjectFifoTypeStorage : TypeStorage { MemRefType elementType; }; -} // namespace detail +} // namespace detail AIEObjectFifoType AIEObjectFifoType::get(MemRefType elementType) { // Call into a helper 'get' method in 'TypeBase' to get an uniqued instance @@ -225,9 +220,8 @@ AIEObjectFifoType AIEObjectFifoType::get(MemRefType elementType) { return Base::get(ctx, elementType); } -LogicalResult -AIEObjectFifoType::verify(function_ref emitError, - MemRefType elementType) { +LogicalResult AIEObjectFifoType::verify( + function_ref emitError, MemRefType elementType) { return success(); } @@ -257,8 +251,8 @@ struct AIEObjectFifoSubviewTypeStorage : TypeStorage { /// Define a construction method for creating a new instance of this storage. /// This method takes an instance of a storage allocator, and an instance of a /// `KeyTy`. - static AIEObjectFifoSubviewTypeStorage * - construct(TypeStorageAllocator &allocator, const KeyTy &key) { + static AIEObjectFifoSubviewTypeStorage *construct( + TypeStorageAllocator &allocator, const KeyTy &key) { // Allocate the storage instance and construct it. return new (allocator.allocate()) AIEObjectFifoSubviewTypeStorage(key); @@ -266,7 +260,7 @@ struct AIEObjectFifoSubviewTypeStorage : TypeStorage { MemRefType elementType; }; -} // namespace detail +} // namespace detail AIEObjectFifoSubviewType AIEObjectFifoSubviewType::get(MemRefType elementType) { // Call into a helper 'get' method in 'TypeBase' to get a uniqued instance @@ -276,9 +270,8 @@ AIEObjectFifoSubviewType AIEObjectFifoSubviewType::get(MemRefType elementType) { } /// This method is used to verify the construction invariants. -LogicalResult -AIEObjectFifoSubviewType::verify(function_ref emitError, - MemRefType elementType) { +LogicalResult AIEObjectFifoSubviewType::verify( + function_ref emitError, MemRefType elementType) { return success(); } @@ -302,8 +295,9 @@ static OptionalParseResult aieTypeParser(DialectAsmParser &parser, // Check that the type is a MemRef type. if (!llvm::isa(elementType)) { - parser.emitError(typeLoc, "element type for an objectFifo must be " - "a MemRefType, got: ") + parser.emitError(typeLoc, + "element type for an objectFifo must be " + "a MemRefType, got: ") << elementType; return failure(); } @@ -312,27 +306,25 @@ static OptionalParseResult aieTypeParser(DialectAsmParser &parser, } if (name == "objectfifosubview") { - if (parser.parseLess()) - return failure(); + if (parser.parseLess()) return failure(); // Parse the element type of the struct. MemRefType elementType; // Parse the current element type. SMLoc typeLoc = parser.getCurrentLocation(); - if (parser.parseType(elementType)) - return failure(); + if (parser.parseType(elementType)) return failure(); // Check that the type is a MemRefType. if (!llvm::isa(elementType)) { - parser.emitError(typeLoc, "element type for a subview must be " - "a MemRefType, got: ") + parser.emitError(typeLoc, + "element type for a subview must be " + "a MemRefType, got: ") << elementType; return failure(); } // Parse: `>` - if (parser.parseGreater()) - return failure(); + if (parser.parseGreater()) return failure(); return result = AIEObjectFifoSubviewType::get(elementType), success(); } @@ -345,7 +337,6 @@ static OptionalParseResult aieTypeParser(DialectAsmParser &parser, /// refer to a type defined in this dialect. static ParseResult parse(Type &result, StringRef name, DialectAsmParser &parser) { - if (OptionalParseResult parseResult = aieTypeParser(parser, name, result); parseResult.has_value()) return parseResult.value(); @@ -359,8 +350,7 @@ static ParseResult parse(Type &result, StringRef name, Type AIEDialect::parseType(DialectAsmParser &parser) const { StringRef name; Type result; - if (parser.parseKeyword(&name) || parse(result, name, parser)) - return {}; + if (parser.parseKeyword(&name) || parse(result, name, parser)) return {}; return result; } @@ -393,7 +383,7 @@ void AIEDialect::initialize() { addInterfaces(); } -} // namespace xilinx::AIE +} // namespace xilinx::AIE // Check that the operation only contains terminators in // TerminatorOpTypes. @@ -449,7 +439,7 @@ LogicalResult HasValidDMAChannels::verifyTrait(Operation *op) { // check for duplicate DMA channels within the same MemTileDMAOp if (auto dmaStart = dyn_cast(bodyOp)) { DMAChannel dmaChan = {dmaStart.getChannelDir(), - dmaStart.getChannelIndex()}; + static_cast(dmaStart.getChannelIndex())}; if (usedChannels.count(dmaChan)) return dmaStart.emitOpError() << "duplicate DMA channel " @@ -468,14 +458,16 @@ LogicalResult HasValidDMAChannels::verifyTrait(Operation *op) { LogicalResult ObjectFifoCreateOp::verify() { if (isa(getElemNumber())) { if (size_t numDepths = dyn_cast(getElemNumber()).size(); - numDepths != getConsumerTiles().size() + 1) // +1 for producer depth - return emitOpError("does not have enough depths specified for producer " - "and for each consumer."); + numDepths != getConsumerTiles().size() + 1) // +1 for producer depth + return emitOpError( + "does not have enough depths specified for producer " + "and for each consumer."); } if (getProducerTileOp().isShimTile() && !getDimensionsToStream().empty()) { - return emitError("`toStream` data layout transformations are not supported " - "on shim tile producers"); + return emitError( + "`toStream` data layout transformations are not supported " + "on shim tile producers"); } return success(); @@ -491,8 +483,7 @@ ParseResult parseObjectFifoProducerTile(OpAsmParser &parser, OpAsmParser::UnresolvedOperand &operand, BDDimLayoutArrayAttr &dimensions) { std::vector emptyDims = {}; - if (parser.parseOperand(operand)) - return failure(); + if (parser.parseOperand(operand)) return failure(); if (succeeded(parser.parseOptionalKeyword("toStream"))) { if (parser.parseCustomAttributeWithFallback( dimensions)) { @@ -569,7 +560,7 @@ void printObjectFifoConsumerTiles(OpAsmPrinter &printer, Operation *op, } } -} // namespace xilinx::AIE +} // namespace xilinx::AIE //===----------------------------------------------------------------------===// // ObjectFifoLinkOp @@ -577,70 +568,73 @@ void printObjectFifoConsumerTiles(OpAsmPrinter &printer, Operation *op, LogicalResult ObjectFifoLinkOp::verify() { if (isJoin() && isDistribute()) - return emitError("ObjectFifoLinkOp does not support 'join' and " - "'distribute' at the same time"); + return emitError( + "ObjectFifoLinkOp does not support 'join' and " + "'distribute' at the same time"); if (auto sharedTile = getOptionalSharedTile(); !sharedTile) - return emitError("ObjectFifoLinkOp must have a link point, i.e., a " - "shared tile between objectFifos"); + return emitError( + "ObjectFifoLinkOp must have a link point, i.e., a " + "shared tile between objectFifos"); if (isJoin()) { ObjectFifoCreateOp fifoOut = getOutputObjectFifos()[0]; auto elemType = llvm::cast(fifoOut.getElemType()).getElementType(); int64_t outputSize = 1; - for (auto dim : elemType.getShape()) - outputSize *= dim; + for (auto dim : elemType.getShape()) outputSize *= dim; int inputSize = 0; for (auto fifoIn : getInputObjectFifos()) { auto elemType = llvm::cast(fifoIn.getElemType()).getElementType(); int64_t nextInputSize = 1; - for (int64_t dim : elemType.getShape()) - nextInputSize *= dim; + for (int64_t dim : elemType.getShape()) nextInputSize *= dim; inputSize += nextInputSize; } if (inputSize != outputSize) - return emitError("Total size of input objFifos in ObjectFifoLinkOp must " - "be equal to size of output objFifo"); + return emitError( + "Total size of input objFifos in ObjectFifoLinkOp must " + "be equal to size of output objFifo"); } else if (isDistribute()) { ObjectFifoCreateOp fifoIn = getInputObjectFifos()[0]; if (!fifoIn.getDimensionsToStream().empty()) { - return emitOpError("currently does not support objectFifos with " - "dimensionsToStream."); + return emitOpError( + "currently does not support objectFifos with " + "dimensionsToStream."); } for (auto dims : fifoIn.getDimensionsFromStreamPerConsumer()) { if (!dims.empty()) - return emitOpError("currently does not support objectFifos with " - "dimensionsFromStreamPerConsumer."); + return emitOpError( + "currently does not support objectFifos with " + "dimensionsFromStreamPerConsumer."); } auto elemType = llvm::cast(fifoIn.getElemType()).getElementType(); int64_t inputSize = 1; - for (auto dim : elemType.getShape()) - inputSize *= dim; + for (auto dim : elemType.getShape()) inputSize *= dim; int outputSize = 0; for (auto fifoOut : getOutputObjectFifos()) { for (auto dims : fifoOut.getDimensionsFromStreamPerConsumer()) { if (!dims.empty()) - return emitOpError("currently does not support objectFifos with " - "dimensionsFromStreamPerConsumer."); + return emitOpError( + "currently does not support objectFifos with " + "dimensionsFromStreamPerConsumer."); } auto elemType = llvm::cast(fifoOut.getElemType()).getElementType(); int64_t nextOutputSize = 1; - for (int64_t dim : elemType.getShape()) - nextOutputSize *= dim; + for (int64_t dim : elemType.getShape()) nextOutputSize *= dim; outputSize += nextOutputSize; } if (outputSize != inputSize) - return emitError("Total size of output objFifos in ObjectFifoLinkOp must " - "be equal to size of input objFifo"); + return emitError( + "Total size of output objFifos in ObjectFifoLinkOp must " + "be equal to size of input objFifo"); } return success(); @@ -650,16 +644,14 @@ std::optional ObjectFifoLinkOp::getOptionalSharedTile() { if (isJoin()) { auto fifoOut = getOutputObjectFifos()[0]; for (auto fifoIn : getInputObjectFifos()) - if (fifoOut.getProducerTile() != fifoIn.getConsumerTiles()[0]) - return {}; + if (fifoOut.getProducerTile() != fifoIn.getConsumerTiles()[0]) return {}; return {fifoOut.getProducerTile()}; } if (isDistribute()) { auto fifoIn = getInputObjectFifos()[0]; for (auto fifoOut : getOutputObjectFifos()) - if (fifoIn.getConsumerTiles()[0] != fifoOut.getProducerTile()) - return {}; + if (fifoIn.getConsumerTiles()[0] != fifoOut.getProducerTile()) return {}; return {fifoIn.getConsumerTiles()[0]}; } @@ -709,8 +701,7 @@ std::vector ObjectFifoLinkOp::getOutputObjectFifos() { //===----------------------------------------------------------------------===// LogicalResult ObjectFifoRegisterExternalBuffersOp::verify() { - if (!getTileOp().isShimTile()) - return emitOpError("tile is not a shim tile"); + if (!getTileOp().isShimTile()) return emitOpError("tile is not a shim tile"); return success(); } @@ -736,8 +727,7 @@ ObjectFifoCreateOp ObjectFifoRegisterExternalBuffersOp::getObjectFifo() { //===----------------------------------------------------------------------===// LogicalResult ObjectFifoAcquireOp::verify() { - if (acqNumber() < 1) - return emitOpError("must acquire at least one element"); + if (acqNumber() < 1) return emitOpError("must acquire at least one element"); auto parent = getOperation()->getParentOfType(); if (parent == nullptr) @@ -794,8 +784,7 @@ ObjectFifoCreateOp ObjectFifoAcquireOp::getObjectFifo() { //===----------------------------------------------------------------------===// LogicalResult ObjectFifoReleaseOp::verify() { - if (relNumber() < 1) - return emitOpError("must release at least one element"); + if (relNumber() < 1) return emitOpError("must release at least one element"); auto parent = getOperation()->getParentOfType(); if (parent == nullptr) @@ -848,8 +837,9 @@ LogicalResult ObjectFifoSubviewAccessOp::verify() { if (auto acqOp = getSubview().getDefiningOp(); getIndex() >= acqOp.acqNumber()) - return emitOpError("accessed farther than number of acquired elements " - "(index out of bounds)."); + return emitOpError( + "accessed farther than number of acquired elements " + "(index out of bounds)."); return success(); } @@ -859,8 +849,7 @@ LogicalResult ObjectFifoSubviewAccessOp::verify() { //===----------------------------------------------------------------------===// LogicalResult ObjectFifoRegisterProcessOp::verify() { - if (getProcessLength() < 1) - return emitOpError("process length must be >= 1"); + if (getProcessLength() < 1) return emitOpError("process length must be >= 1"); if (getAcquirePattern().size() != getReleasePattern().size()) { // acquire pattern size = process length (i.e., release pattern will be @@ -979,11 +968,9 @@ LogicalResult GetCascadeOp::verify() { DataLayout dataLayout = DataLayout::closest(*this); auto bits = dataLayout.getTypeSizeInBits(type); if (targetModel.getTargetArch() == AIEArch::AIE1) { - if (bits != 384) - return emitOpError("must be a 384-bit type"); + if (bits != 384) return emitOpError("must be a 384-bit type"); } else if (targetModel.getTargetArch() == AIEArch::AIE2) { - if (bits != 512) - return emitOpError("must be a 512-bit type"); + if (bits != 512) return emitOpError("must be a 512-bit type"); } else return emitOpError("cascade not supported in ") << stringifyAIEArch(targetModel.getTargetArch()); @@ -1023,8 +1010,7 @@ LogicalResult TileOp::verify() { bool found = false; for (auto *user : users) { if (llvm::isa(*user)) { - if (found) - return emitOpError("can only have one switchbox"); + if (found) return emitOpError("can only have one switchbox"); found = true; } } @@ -1111,8 +1097,7 @@ bool isLegalTileConnection(TileOp tile, const AIETargetModel &targetModel, LogicalResult ShimSwitchboxOp::verify() { Region &body = getConnections(); DenseSet destset; - if (body.empty()) - return emitOpError("should have non-empty body"); + if (body.empty()) return emitOpError("should have non-empty body"); for (auto &ops : body.front()) { if (auto connectOp = dyn_cast(ops)) { @@ -1139,8 +1124,7 @@ LogicalResult ShimSwitchboxOp::verify() { LogicalResult ShimMuxOp::verify() { Region &body = getConnections(); DenseSet destset; - if (body.empty()) - return emitOpError("should have non-empty body"); + if (body.empty()) return emitOpError("should have non-empty body"); for (auto &ops : body.front()) { if (auto connectOp = dyn_cast(ops)) { @@ -1191,8 +1175,7 @@ LogicalResult ShimDMAOp::verify() { std::vector inputChannels; std::vector outputChannels; - if (getBody().empty()) - return emitOpError("should have non-empty body"); + if (getBody().empty()) return emitOpError("should have non-empty body"); if (!getTileOp().isShimNOCTile()) return emitOpError("must be in a ShimTile with a NOC connection"); @@ -1205,7 +1188,7 @@ LogicalResult ShimDMAOp::verify() { // check for duplicate DMA channels within the same ShimDMAOp if (auto dmaStart = dyn_cast(bodyOp)) { DMAChannel dmaChan = {dmaStart.getChannelDir(), - dmaStart.getChannelIndex()}; + static_cast(dmaStart.getChannelIndex())}; if (usedChannels.count(dmaChan)) return dmaStart.emitOpError() << "duplicate DMA channel " @@ -1248,8 +1231,7 @@ LogicalResult PacketRulesOp::verify() { LogicalResult PacketFlowOp::verify() { Region &body = getPorts(); - if (body.empty()) - return emitOpError("should have non-empty body"); + if (body.empty()) return emitOpError("should have non-empty body"); for (auto &ops : body.front()) { if (!isa(ops)) @@ -1264,8 +1246,7 @@ LogicalResult PacketFlowOp::verify() { //===----------------------------------------------------------------------===// LogicalResult CoreOp::verify() { - if (getBody().empty()) - return emitOpError("should have non-empty body"); + if (getBody().empty()) return emitOpError("should have non-empty body"); if (getTileOp().isShimTile()) return emitOpError("CoreOp cannot be created on shim tile, i.e. row == 0"); if (getTileOp().isMemTile()) @@ -1291,8 +1272,7 @@ int64_t BufferOp::getAllocationSize() { TileOp BufferOp::getTileOp() { return cast(getTile().getDefiningOp()); } LogicalResult BufferOp::verify() { - if (UsesAreAccessable::verifyTrait(*this).failed()) - return failure(); + if (UsesAreAccessable::verifyTrait(*this).failed()) return failure(); return success(); } @@ -1342,12 +1322,10 @@ static ParseResult parseBufferInitialValue(OpAsmParser &parser, Type &type, return parser.emitError(parser.getNameLoc()) << "type should be static shaped memref, but got " << type; - if (parser.parseOptionalEqual()) - return success(); + if (parser.parseOptionalEqual()) return success(); Type tensorType = mlir::memref::getTensorTypeFromMemRefType(memrefType); - if (parser.parseAttribute(initialValue, tensorType)) - return failure(); + if (parser.parseAttribute(initialValue, tensorType)) return failure(); if (!llvm::isa(initialValue)) return parser.emitError(parser.getNameLoc()) << "initial value should be an elements attribute"; @@ -1363,8 +1341,7 @@ LogicalResult MemOp::verify() { DenseSet usedChannels; std::vector inputChannels; std::vector outputChannels; - if (body.empty()) - return emitOpError("should have non-empty body"); + if (body.empty()) return emitOpError("should have non-empty body"); if (HasSomeTerminator::verifyTrait(*this) .failed()) @@ -1374,7 +1351,7 @@ LogicalResult MemOp::verify() { // check for duplicate DMA channels within the same MemOp if (auto dmaStart = dyn_cast(bodyOp)) { DMAChannel dmaChan = {dmaStart.getChannelDir(), - dmaStart.getChannelIndex()}; + static_cast(dmaStart.getChannelIndex())}; if (usedChannels.count(dmaChan)) return dmaStart.emitOpError() << "duplicate DMA channel " @@ -1442,7 +1419,8 @@ LogicalResult MemTileDMAOp::verify() { if (auto startOp = dyn_cast(bodyOp)) { // check if number of input and output channels is more than available // hardware - DMAChannel dmaChan = {startOp.getChannelDir(), startOp.getChannelIndex()}; + DMAChannel dmaChan = {startOp.getChannelDir(), + static_cast(startOp.getChannelIndex())}; if (dmaChan.direction == DMAChannelDir::S2MM) inputChannels.push_back(dmaChan); else @@ -1461,8 +1439,7 @@ LogicalResult MemTileDMAOp::verify() { worklist.push_back(firstBD); while (!worklist.empty()) { Block *block = worklist.pop_back_val(); - if (block->empty()) - continue; + if (block->empty()) continue; auto successors = block->getTerminator()->getSuccessors(); for (auto *i : successors) { if (!reachable.contains(i)) { @@ -1556,8 +1533,9 @@ LogicalResult DMABDOp::verify() { "BDs only support BufferOp or ExternalBufferOp operands."); if (getLenInBytes() % 4) - return emitOpError("transfer length must be multiple of 4 (i.e., represent " - "4 byte aligned address)"); + return emitOpError( + "transfer length must be multiple of 4 (i.e., represent " + "4 byte aligned address)"); TileID parentTileId = getParentTileElement(getOperation()).getTileID(); @@ -1688,8 +1666,7 @@ LogicalResult SwitchboxOp::verify() { DenseSet destset; auto tile = getTileOp(); const auto &targetModel = getTargetModel(tile); - if (body.empty()) - return emitOpError("should have non-empty body"); + if (body.empty()) return emitOpError("should have non-empty body"); for (auto &ops : body.front()) { // Would be simpler if this could be templatized. auto checkBound = [&ops](StringRef dir, WireBundle bundle, int index, @@ -1819,8 +1796,7 @@ struct HasSomeParent { static LogicalResult verifyTrait(Operation *op) { Operation *operation = op->getParentOp(); while (operation) { - if (llvm::isa_and_nonnull(operation)) - return success(); + if (llvm::isa_and_nonnull(operation)) return success(); operation = operation->getParentOp(); } return failure(); @@ -1857,8 +1833,7 @@ struct UsesOneLockInDMABlock { for (auto op : block->getOps()) { if (auto lock = dyn_cast(op.getLock().getDefiningOp()); lock.getLockID().has_value()) { - if (lockID != -1 && lockID != lock.getLockIDValue()) - return failure(); + if (lockID != -1 && lockID != lock.getLockIDValue()) return failure(); lockID = lock.getLockIDValue(); } } @@ -1913,8 +1888,7 @@ LogicalResult UseLockOp::verify() { // Otherwise, AIE.useLock should be inside MemOp, MemTileDMAOp, or ShimDMAOp, if (HasSomeParent::verifyTrait(*this) .succeeded()) { - if (!(*this)->getBlock()) - return (*this)->emitOpError("is not in a block."); + if (!(*this)->getBlock()) return (*this)->emitOpError("is not in a block."); if (targetModel.getTargetArch() == AIEArch::AIE1 && UsesOneLockInDMABlock::verifyTrait(*this).failed()) @@ -1964,20 +1938,20 @@ size_t SwitchboxOp::getNumDestConnections(WireBundle bundle) { WireBundle getConnectingBundle(WireBundle dir) { switch (dir) { - case WireBundle::North: - return WireBundle::South; - case WireBundle::South: - return WireBundle::North; - case WireBundle::East: - return WireBundle::West; - case WireBundle::West: - return WireBundle::East; - default: - return dir; + case WireBundle::North: + return WireBundle::South; + case WireBundle::South: + return WireBundle::North; + case WireBundle::East: + return WireBundle::West; + case WireBundle::West: + return WireBundle::East; + default: + return dir; } } -} // namespace xilinx::AIE +} // namespace xilinx::AIE // Include implementations for custom attributes #define GET_ATTRDEF_CLASSES diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index 2f7d8d8b5..f15f8b3fe 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -12,9 +12,6 @@ #define MLIR_AIE_DIALECT_H #include "AIEEnums.h" - -#include "AIETargetModel.h" - #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -44,20 +41,34 @@ struct HasValidDMAChannels static mlir::LogicalResult verifyTrait(mlir::Operation *op); }; -class TileOp; -} // namespace xilinx::AIE +template +bool hasName(T &op) { + return bool(op.getOperation()->template getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())); +} + +template +mlir::StringAttr name(T &op) { + if (auto attr = op.getOperation()->template getAttrOfType( + mlir::SymbolTable::getSymbolAttrName())) + return attr; + op.emitOpError("does not have '") + << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; + llvm::report_fatal_error("couldn't get name"); +} +} // namespace xilinx::AIE namespace xilinx::AIE { -mlir::LogicalResult -verifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op); -} // namespace xilinx::AIE +mlir::LogicalResult verifyOffsetSizeAndStrideOp( + mlir::OffsetSizeAndStrideOpInterface op); +} // namespace xilinx::AIE /// Include the generated interface declarations. #include "aie/AIEInterfaces.h.inc" namespace xilinx::AIE { -mlir::LogicalResult -myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op); +mlir::LogicalResult myVerifyOffsetSizeAndStrideOp( + mlir::OffsetSizeAndStrideOpInterface op); template struct MyOffsetSizeAndStrideOpInterfaceTrait : public ::mlir::detail::OffsetSizeAndStrideOpInterfaceTrait { @@ -72,7 +83,7 @@ struct MyOffsetSizeAndStrideOpInterface template struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait {}; }; -} // namespace xilinx::AIE +} // namespace xilinx::AIE // Include dialect declarations such as parseAttributes, parseType #include "aie/AIEDialect.h.inc" @@ -81,7 +92,7 @@ namespace xilinx::AIE { void registerAIETranslations(); -} // namespace xilinx::AIE +} // namespace xilinx::AIE //////////////////////////////////////////////////////////////////////////////// /////////////////////// Custom Types for the Dialect /////////////////////////// @@ -96,7 +107,7 @@ struct AIEObjectFifoTypeStorage; class AIEObjectFifoType : public mlir::Type::TypeBase { -public: + public: /// Inherit some necessary constructors from 'TypeBase'. using Base::Base; @@ -104,9 +115,9 @@ class AIEObjectFifoType static AIEObjectFifoType get(mlir::MemRefType elementType); /// This method is used to verify the construction invariants. - static mlir::LogicalResult - verify(llvm::function_ref emitError, - mlir::MemRefType elementType); + static mlir::LogicalResult verify( + llvm::function_ref emitError, + mlir::MemRefType elementType); static constexpr llvm::StringLiteral name = "objectfifo"; /// Returns the element type of this ObjectFifoType. @@ -121,7 +132,7 @@ struct AIEObjectFifoSubviewTypeStorage; class AIEObjectFifoSubviewType : public mlir::Type::TypeBase { -public: + public: /// Inherit some necessary constructors from 'TypeBase'. using Base::Base; @@ -129,16 +140,16 @@ class AIEObjectFifoSubviewType static AIEObjectFifoSubviewType get(mlir::MemRefType elementType); /// This method is used to verify the construction invariants. - static mlir::LogicalResult - verify(llvm::function_ref emitError, - mlir::MemRefType elementType); + static mlir::LogicalResult verify( + llvm::function_ref emitError, + mlir::MemRefType elementType); static constexpr llvm::StringLiteral name = "objectfifosubview"; /// Returns the element type of this SubviewType. mlir::MemRefType getElementType(); }; -} // namespace xilinx::AIE +} // namespace xilinx::AIE //////////////////////////////////////////////////////////////////////////////// // Custom Attributes /////////////////////////////////////////////////////////// @@ -155,11 +166,11 @@ namespace xilinx::AIE { WireBundle getConnectingBundle(WireBundle dir); -#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP) \ - friend std::string to_string(const TYPE_WITH_INSERTION_OP &s) { \ - std::ostringstream ss; \ - ss << s; \ - return ss.str(); \ +#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP) \ + friend std::string to_string(const TYPE_WITH_INSERTION_OP &s) { \ + std::ostringstream ss; \ + ss << s; \ + return ss.str(); \ } typedef struct Port { @@ -179,27 +190,27 @@ typedef struct Port { friend std::ostream &operator<<(std::ostream &os, const Port &port) { os << "("; switch (port.bundle) { - case WireBundle::Core: - os << "Core"; - break; - case WireBundle::DMA: - os << "DMA"; - break; - case WireBundle::North: - os << "N"; - break; - case WireBundle::East: - os << "E"; - break; - case WireBundle::South: - os << "S"; - break; - case WireBundle::West: - os << "W"; - break; - default: - os << "X"; - break; + case WireBundle::Core: + os << "Core"; + break; + case WireBundle::DMA: + os << "DMA"; + break; + case WireBundle::North: + os << "N"; + break; + case WireBundle::East: + os << "E"; + break; + case WireBundle::South: + os << "S"; + break; + case WireBundle::West: + os << "W"; + break; + default: + os << "X"; + break; } os << ": " << std::to_string(port.channel) << ")"; return os; @@ -236,10 +247,9 @@ typedef struct DMAChannel { const AIETargetModel &getTargetModel(mlir::Operation *op); const AIETargetModel &getTargetModel(AIEDevice device); -mlir::ParseResult -parseObjectFifoProducerTile(mlir::OpAsmParser &parser, - mlir::OpAsmParser::UnresolvedOperand &operand, - BDDimLayoutArrayAttr &dimensions); +mlir::ParseResult parseObjectFifoProducerTile( + mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, + BDDimLayoutArrayAttr &dimensions); void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::Value tile, @@ -256,7 +266,7 @@ void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, int32_t getBufferBaseAddress(mlir::Operation *bufOp); -} // namespace xilinx::AIE +} // namespace xilinx::AIE // include TableGen generated Op definitions #define GET_OP_CLASSES @@ -270,7 +280,7 @@ void collectTiles(DeviceOp &device, void collectBuffers( DeviceOp &device, llvm::DenseMap> &buffers); -} // namespace xilinx::AIE +} // namespace xilinx::AIE namespace llvm { // Functions hash just like pointers. @@ -295,7 +305,7 @@ struct DenseMapInfo { return lhs == rhs; } }; -} // namespace llvm +} // namespace llvm namespace llvm { // Functions hash just like pointers. @@ -369,7 +379,7 @@ struct DenseMapInfo { } }; -} // namespace llvm +} // namespace llvm template <> struct std::less { diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index 56562078d..977f9a1cf 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -60,9 +60,6 @@ def AIE_DeviceOp: AIE_Op<"device", [ let assemblyFormat = [{ `(` $device `)` regions attr-dict }]; - let extraClassDeclaration = [{ - const xilinx::AIE::AIETargetModel &getTargetModel(); - }]; let hasVerifier = 1; } @@ -90,36 +87,6 @@ def AIE_TileOp: AIE_Op<"tile", [ the AIE array proper and the PL. The South-West/Lower Right most core exists in Tile(0,1) }]; - let extraClassDeclaration = [{ - size_t getNumSourceConnections(WireBundle bundle); - size_t getNumDestConnections(WireBundle bundle); - int colIndex() { return getCol(); } - int rowIndex() { return getRow(); } - TileID getTileID() { return {getCol(), getRow()}; } - bool isShimTile() { return getRow() == 0; } - bool isMemTile(); - bool isShimNOCTile(); - bool isShimPLTile(); - bool isShimNOCorPLTile(); - bool isInternalMemWest() { return ((rowIndex() % 2) == 0); }; - - MemOp getMemOp() { - auto users = getResult().getUsers(); - for(auto user : users) - if(auto memOp = llvm::dyn_cast(*user)) - return memOp; - return nullptr; - } - - CoreOp getCoreOp() { - auto users = getResult().getUsers(); - for(auto user : users) - if(auto coreOp = llvm::dyn_cast(*user)) - return coreOp; - return nullptr; - } - }]; - let assemblyFormat = [{ `(` $col `,` $row `)` attr-dict }]; @@ -172,11 +139,6 @@ def AIE_SwitchboxOp: AIE_Op<"switchbox", [ let hasVerifier = 1; let extraClassDeclaration = [{ - size_t getNumSourceConnections(WireBundle bundle); - size_t getNumDestConnections(WireBundle bundle); - int colIndex(); - int rowIndex(); - TileOp getTileOp(); using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; }]; } @@ -233,57 +195,52 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ let hasVerifier = 1; let extraClassDeclaration = [{ - int colIndex(); - int rowIndex(); - size_t getNumSourceConnections(WireBundle bundle); - size_t getNumDestConnections(WireBundle bundle); - TileOp getTileOp(); using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; }]; } -def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ - FlowEndPoint, TileElement, HasValidBDs, - HasValidDMAChannels, IsShimNOCTile, - DeclareOpInterfaceMethods - ]>, Results<(outs Index)> { - let arguments = ( - ins Index:$tile - ); - let summary = "Declare a DMA in the PL shim"; - let description = [{ - This operation creates a DMA that belongs to a shim tile. - The region of a ShimDMAOp is used to setup the DMAs and Block Descriptors. - - Example: - ``` - %buf = aie.external_buffer : memref<256xi64> - %lock1 = aie.lock(%t70, 1) - - %dma = aie.shim_dma(%t70) { - aie.dma_start(MM2S, 0, ^bd0, ^end) - ^bd0: - aie.use_lock(%lock1, Acquire, 1) - aie.dma_bd(%buf : memref<512 x i16>, 0, 512) - aie.use_lock(%lock1, Release, 0) - aie.next_bd ^bd0 - ^end: - aie.end - } - ``` - Create the shim_dma for tile `%t70` and setup one DMA channel and one Buffer Descriptor. - }]; - let regions = (region AnyRegion:$body); - let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; - let hasVerifier = 1; - - let extraClassDeclaration = [{ - int colIndex(); - int rowIndex(); - TileOp getTileOp(); - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; -} +// def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ +// FlowEndPoint, TileElement, HasValidBDs, +// HasValidDMAChannels, IsShimNOCTile, +// DeclareOpInterfaceMethods +// ]>, Results<(outs Index)> { +// let arguments = ( +// ins Index:$tile +// ); +// let summary = "Declare a DMA in the PL shim"; +// let description = [{ +// This operation creates a DMA that belongs to a shim tile. +// The region of a ShimDMAOp is used to setup the DMAs and Block Descriptors. +// +// Example: +// ``` +// %buf = aie.external_buffer : memref<256xi64> +// %lock1 = aie.lock(%t70, 1) +// +// %dma = aie.shim_dma(%t70) { +// aie.dma_start(MM2S, 0, ^bd0, ^end) +// ^bd0: +// aie.use_lock(%lock1, Acquire, 1) +// aie.dma_bd(%buf : memref<512 x i16>, 0, 512) +// aie.use_lock(%lock1, Release, 0) +// aie.next_bd ^bd0 +// ^end: +// aie.end +// } +// ``` +// Create the shim_dma for tile `%t70` and setup one DMA channel and one Buffer Descriptor. +// }]; +// let regions = (region AnyRegion:$body); +// let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; +// let hasVerifier = 1; +// +// let extraClassDeclaration = [{ +// int colIndex(); +// int rowIndex(); +// TileOp getTileOp(); +// using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; +// }]; +// } def AIE_CoreOp: AIE_Op<"core", [ FlowEndPoint, IsCoreTile, TileElement, @@ -331,10 +288,6 @@ def AIE_CoreOp: AIE_Op<"core", [ let hasVerifier = 1; let extraClassDeclaration = [{ - int colIndex(); - int rowIndex(); - bool isMemWest() { return ((rowIndex() % 2) == 0); }; - TileOp getTileOp(); using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; }]; @@ -345,32 +298,6 @@ def AIE_CoreOp: AIE_Op<"core", [ ]; } -def AIE_DebugOp: AIE_Op<"debug", []> { - let arguments = ( - ins AnyType:$arg - ); - let summary = "Capture a value for debugging"; - let description = [{ - Output the given value for debugging. This is primarily used for simulation. - }]; - let assemblyFormat = [{ `(` $arg `:` type($arg) `)` attr-dict }]; -} - -def AIE_PLIOOp: AIE_Op<"plio", [ - DeclareOpInterfaceMethods - ]>, Results<(outs Index)> { - let arguments = (ins I32Attr:$col); - let summary = "Declare an interface to the PL"; - let description = [{ - An interface to the PL. - }]; - let assemblyFormat = [{ `(` $col `)` attr-dict }]; - - let extraClassDeclaration = [{ - int colIndex() { return getCol(); } - }]; -} - def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { let arguments = ( ins WireBundle:$source_bundle, @@ -399,13 +326,6 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> let assemblyFormat = [{ `<` $source_bundle `:` $source_channel `,` $dest_bundle `:` $dest_channel `>` attr-dict }]; - - let extraClassDeclaration = [{ - int sourceIndex() { return getSourceChannel(); } - int destIndex() { return getDestChannel(); } - Port sourcePort() { return {getSourceBundle(), sourceIndex()}; } - Port destPort() { return {getDestBundle(), destIndex()}; } - }]; } def AIE_FlowOp: AIE_Op<"flow", []> { @@ -436,11 +356,6 @@ def AIE_FlowOp: AIE_Op<"flow", []> { let assemblyFormat = [{ `(` $source `,` $source_bundle `:` $source_channel `,` $dest `,` $dest_bundle `:` $dest_channel `)` attr-dict }]; - - let extraClassDeclaration = [{ - int sourceIndex() { return getSourceChannel(); } - int destIndex() { return getDestChannel(); } - }]; } def AIE_AMSelOp: AIE_Op<"amsel", [ @@ -476,11 +391,6 @@ def AIE_AMSelOp: AIE_Op<"amsel", [ `<` $arbiterID `>` `(` $msel `)` attr-dict }]; - let extraClassDeclaration = [{ - int arbiterIndex() { return getArbiterID(); } - int getMselValue() { return getMsel(); } - }]; - let builders = [ OpBuilder<(ins "int":$arbiterID, "int":$msel), [{ @@ -531,30 +441,6 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ let assemblyFormat = [{ `(` $dest_bundle `:` $dest_channel `,` $amsels `)` attr-dict }]; - - let extraClassDeclaration = [{ - int destIndex() { return getDestChannel(); } - Port destPort() { return {getDestBundle(), destIndex()}; } - }]; -} - -def AIE_WireOp: AIE_Op<"wire", []> { - let arguments = ( - ins Index:$source, - WireBundle:$source_bundle, - Index:$dest, - WireBundle:$dest_bundle - ); - let summary = "A bundle of physical wires between components"; - let description = [{ - The `aie.wire` operation represents a physical set of connections between components in a Versal device. - Typically, these components are switches, represented by an `aie.switchbox` operation, and tiles, - represented by an [aie.tile](#aietile-aietileop) operation. - }]; - - let assemblyFormat = [{ - `(` $source `:` $source_bundle `,` $dest `:` $dest_bundle `)` attr-dict - }]; } def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"EndOp">]> { @@ -575,11 +461,6 @@ def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"En let assemblyFormat = [{ `(` $source_bundle `:` $source_channel `)` regions attr-dict }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - int sourceIndex() { return getSourceChannel(); } - Port sourcePort() { return {getSourceBundle(), sourceIndex()}; } - }]; } def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { @@ -620,11 +501,6 @@ def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { ``` }]; - let extraClassDeclaration = [{ - int maskInt() { return getMask(); } - int valueInt() { return getValue(); } - }]; - let assemblyFormat = [{ `(` $mask `,` $value `,` $amsel `)` attr-dict }]; @@ -656,10 +532,6 @@ def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndO let assemblyFormat = [{ `(` $ID `)` regions attr-dict }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - int IDInt() { return getID(); } - }]; } def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { @@ -679,11 +551,6 @@ def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { let assemblyFormat = [{ `<` $tile `,` $bundle `:` $channel `>` attr-dict }]; - - let extraClassDeclaration = [{ - int channelIndex() { return getChannel(); } - Port port() { return {getBundle(), channelIndex()}; } - }]; } def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { @@ -704,11 +571,6 @@ def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { let assemblyFormat = [{ `<` $tile `,` $bundle `:` $channel `>` attr-dict }]; - - let extraClassDeclaration = [{ - int channelIndex() { return getChannel(); } - Port port() { return {getBundle(), channelIndex()}; } - }]; } def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { @@ -740,14 +602,10 @@ def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { let assemblyFormat = [{ `(` $packet_type `,` $packet_id `)` attr-dict }]; - - let extraClassDeclaration = [{ - int getPacketID() { return getPacketId(); } - }]; } def AIE_DMABDOp: AIE_Op<"dma_bd", [ - ParentOneOf<["MemOp", "MemTileDMAOp", "ShimDMAOp", "DMAOp"]>, + ParentOneOf<["MemOp", "MemTileDMAOp"]>, ]> { let summary = "Declare a dma buffer descriptor op"; let description = [{ @@ -878,20 +736,6 @@ def AIE_DMABDOp: AIE_Op<"dma_bd", [ `(` $buffer `:` type($buffer) (`,` $offset^)? (`,` $len^)? (`,` $dimensions^)? (`,` $pad_dimensions^)? (`,` `pad_value` `=` $pad_value^)? `)` attr-dict }]; - let extraClassDeclaration = [{ - BufferOp getBufferOp(); - int32_t getBufferElementTypeWidthInBytes() { - return getBuffer().getType().getElementTypeBitWidth() / 8; - } - int32_t getLenInBytes() { - if (std::optional len = getLen(); len.has_value()) - return len.value() * getBufferElementTypeWidthInBytes(); - else - return getBuffer().getType().getNumElements() * getBufferElementTypeWidthInBytes(); - } - int32_t getOffsetInBytes() { return getOffset() * getBufferElementTypeWidthInBytes(); } - }]; - let hasVerifier = 1; let builders = [ OpBuilder<(ins "mlir::Value":$buffer, "int":$offset, "int":$len), [{ @@ -922,7 +766,7 @@ def AIE_DMABDOp: AIE_Op<"dma_bd", [ } def AIE_DMAStartOp: AIE_Op<"dma_start", [ - ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp", "ShimDMAOp"]>, + ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp"]>, Terminator, DeclareOpInterfaceMethods ]>, Results<(outs I1:$valid)> { @@ -961,47 +805,42 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [ let assemblyFormat = [{ `(` $channel_dir `,` $channel_index `,` $dest `,` $chain (`,` `repeat_count` `=` $repeat_count^)? `)` attr-dict }]; - - let extraClassDeclaration = [{ - bool isSend() { return getChannelDir() == DMAChannelDir::MM2S; } - bool isRecv() { return getChannelDir() == DMAChannelDir::S2MM; } - }]; } -def AIE_DMAOp: AIE_Op<"dma", [ - ParentOneOf<["MemOp", "MemTileDMAOp", "ShimDMAOp"]>, - NoTerminator, - DeclareOpInterfaceMethods, - DeclareOpInterfaceMethods - ]>, Results<(outs I1:$valid)> { - - let summary = "An op to describe a set of DMA operations."; - - let arguments = ( - ins DMAChannelDir:$channel_dir, - ConfinedAttr]>:$channel_index, - DefaultValuedAttr:$loop, - // repeat_count==0 means "do it once" and don't repeat - DefaultValuedAttr:$repeat_count, - OptionalAttr:$sym_name - ); - let regions = (region VariadicRegion>:$bds); - let assemblyFormat = [{ - `(` $channel_dir `,` $channel_index `)` - attr-dict ` ` - `[`regions`]` - }]; - let hasVerifier = 1; - - let extraClassDefinition = [{ - void $cppClass::getAsmResultNames( - llvm::function_ref setNameFn) { - if (auto name = getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())) - setNameFn(getResult(), name.str()); - } - }]; -} +// def AIE_DMAOp: AIE_Op<"dma", [ +// ParentOneOf<["MemOp", "MemTileDMAOp", "ShimDMAOp"]>, +// NoTerminator, +// DeclareOpInterfaceMethods, +// DeclareOpInterfaceMethods +// ]>, Results<(outs I1:$valid)> { +// +// let summary = "An op to describe a set of DMA operations."; +// +// let arguments = ( +// ins DMAChannelDir:$channel_dir, +// ConfinedAttr]>:$channel_index, +// DefaultValuedAttr:$loop, +// // repeat_count==0 means "do it once" and don't repeat +// DefaultValuedAttr:$repeat_count, +// OptionalAttr:$sym_name +// ); +// let regions = (region VariadicRegion>:$bds); +// let assemblyFormat = [{ +// `(` $channel_dir `,` $channel_index `)` +// attr-dict ` ` +// `[`regions`]` +// }]; +// let hasVerifier = 1; +// +// let extraClassDefinition = [{ +// void $cppClass::getAsmResultNames( +// llvm::function_ref setNameFn) { +// if (auto name = getOperation()->getAttrOfType( +// mlir::SymbolTable::getSymbolAttrName())) +// setNameFn(getResult(), name.str()); +// } +// }]; +// } // MemOps are not actually Callable, but we want to inline code into them, so we have to @@ -1039,14 +878,6 @@ def AIE_MemOp: AIE_Op<"mem", [ let hasVerifier = 1; let extraClassDeclaration = [{ - int colIndex(); - int rowIndex(); - TileOp getTileOp(); - int maxSizeInBytes() { return 32768; } - // CallableOpInterface - mlir::Region *getCallableRegion(); - llvm::ArrayRef getArgumentTypes() { return getOperand().getType(); } - llvm::ArrayRef getResultTypes() { return getType(); } using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; }]; } @@ -1090,19 +921,12 @@ def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ let hasVerifier = 1; let extraClassDeclaration = [{ - int colIndex(); - int rowIndex(); - TileOp getTileOp(); - // CallableOpInterface - mlir::Region *getCallableRegion(); - llvm::ArrayRef getArgumentTypes() { return getOperand().getType(); } - llvm::ArrayRef getResultTypes() { return getType(); } using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; }]; } def AIE_NextBDOp: AIE_Op<"next_bd", [ - Terminator, ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp", "ShimDMAOp"]> + Terminator, ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp"]> ]> { let summary = "The next buffer descriptor"; let description = [{ @@ -1164,32 +988,10 @@ def AIE_LockOp: AIE_Op<"lock", [ let assemblyFormat = [{ `(` $tile (`,` $lockID^ )? `)` attr-dict }]; let extraClassDeclaration = [{ - bool hasName() { - return bool(getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())); - } - - mlir::StringAttr name() { - if (auto attr = getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())) - return attr; - emitOpError("does not have '") - << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; - llvm::report_fatal_error("couldn't get name"); - } - - int getLockIDValue() { - assert(getLockID().has_value() && "Lock has no ID value"); - return getLockID().value(); - } - - int colIndex(); - int rowIndex(); - TileOp getTileOp(); void getAsmResultNames( llvm::function_ref setNameFn) { - if (hasName()) - setNameFn(getResult(), name().str()); + if (hasName(*this)) + setNameFn(getResult(), name(*this).str()); else { std::string nameWithoutDialect = getOperationName().str().substr(getOperationName().find('.') + 1); @@ -1245,22 +1047,6 @@ def AIE_UseLockOp: AIE_Op<"use_lock", []> { build($_builder, $_state, lock, action, $_builder.getI32IntegerAttr(value), nullptr); }]> ]; - - let extraClassDeclaration = [{ - bool acquire() { return (getAction() == LockAction::Acquire); } - bool acquireGE() { return (getAction() == LockAction::AcquireGreaterEqual); } - bool release() { return (getAction() == LockAction::Release); } - int getLockValue() { return getValue().value_or(1); } - int getTimeout() { - // LockBlocking is an EnumAttr. - if (auto val = getBlocking()) - return (int)*val; - return 1; - } - LockOp getLockOp() { - return llvm::cast(getLock().getDefiningOp()); - } - }]; } def AIE_BufferOp: AIE_Op<"buffer", [ @@ -1295,34 +1081,13 @@ def AIE_BufferOp: AIE_Op<"buffer", [ let hasVerifier = 1; let extraClassDeclaration = [{ - bool hasName() { - return bool(getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())); - } - - mlir::StringAttr name() { - if (auto attr = getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())) - return attr; - emitOpError("does not have '") - << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; - llvm::report_fatal_error("couldn't get name"); - } - - // Return the number of bytes that need to be allocated for this buffer. - int64_t getAllocationSize(); - TileOp getTileOp(); void getAsmResultNames( - llvm::function_ref setNameFn) { - if (hasName()) - setNameFn(getResult(), name().str()); - else { - std::string nameWithoutDialect = - getOperationName().str().substr(getOperationName().find('.') + 1); - setNameFn(getResult(), nameWithoutDialect + "_" + - std::to_string(getTileID().col) + "_" + - std::to_string(getTileID().row)); - } + llvm::function_ref setNameFn) { + std::string nameWithoutDialect = + getOperationName().str().substr(getOperationName().find('.') + 1); + setNameFn(getResult(), nameWithoutDialect + "_" + + std::to_string(getTileID().col) + "_" + + std::to_string(getTileID().row)); } }]; } @@ -1353,163 +1118,147 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ let results = (outs AnyMemRef:$buffer); let assemblyFormat = [{ attr-dict `:` type($buffer) }]; - let extraClassDeclaration = [{ - bool hasName() { - return bool(getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())); - } - - mlir::StringAttr name() { - if (auto attr = getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())) - return attr; - emitOpError("does not have '") - << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; - llvm::report_fatal_error("couldn't get name"); - } - }]; - let extraClassDefinition = [{ void $cppClass::getAsmResultNames( llvm::function_ref setNameFn) { - if (hasName()) - setNameFn(getResult(), name().str()); - } - }]; -} - -def AIE_EventOp: AIE_Op<"event", []> { - let summary = "Event instruction"; - let description = [{ - Event instruction. - }]; - let arguments = (ins ConfinedAttr, IntMaxValue<1>]>:$val); - let results = (outs); - let assemblyFormat = [{ - `(` $val `)` attr-dict - }]; -} - -def AIE_GetStreamOp: AIE_Op<"get_stream", [ - HasParent<"CoreOp"> - ]>, Results<(outs AnyTypeOf<[F32, I32, I<128>]>)> { - let summary = "An op to read from a stream channel/port of a switchbox"; - let description = [{ - An op to read from a stream channel/port of a switchbox. - }]; - - let arguments = (ins AnyInteger:$channel); - let results = (outs AnyTypeOf<[F32, I32, I<128>]>:$stream_value); - - let assemblyFormat = [{ - `(` $channel `:` type($channel) `)` attr-dict `:` type($stream_value) - }]; - - let extraClassDeclaration = [{ - bool isWideStream() { return getStreamValue().getType().isInteger(128); } - bool isFloatStream() { - return llvm::isa(getStreamValue().getType()); + if (hasName(*this)) + setNameFn(getResult(), name(*this).str()); } }]; } -def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { - let summary = "An op to write to a stream channel/port of a switchbox"; - let description = [{ - An op to write to a stream channel/port of a switchbox. - }]; - - let arguments = ( - ins AnyInteger:$channel, - AnyTypeOf<[F32, I32, I<128>]>:$stream_value - ); - - let assemblyFormat = [{ - `(` $channel `:` type($channel) `,` $stream_value `:` type($stream_value) `)` attr-dict - }]; - - let extraClassDeclaration = [{ - bool isWideStream() { return getStreamValue().getType().isInteger(128); } - bool isFloatStream() { - return llvm::isa(getStreamValue().getType()); - } - }]; -} - -def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { - let arguments = ( - ins Index:$source_tile, - Index:$dest_tile - ); - let summary = "A cascade connection between tiles"; - let description = [{ - The `aie.cascade_flow` operation represents a cascade connection between two `aie.tile` operations. - During lowering, this is replaced by `aie.configure_cascade` operations for each `aie.tile` based on - their relative placement to one another. - - Example: - ``` - %tile03 = aie.tile(0, 3) - %tile13 = aie.tile(1, 3) - aie.cascade_flow(%tile03, %tile13) - ``` - }]; - let hasVerifier = 1; - let assemblyFormat = [{ - `(` $source_tile `,` $dest_tile `)` attr-dict - }]; - let extraClassDeclaration = [{ - TileOp getSourceTileOp(); - TileOp getDestTileOp(); - }]; -} - -def AIE_ConfigureCascadeOp: AIE_Op<"configure_cascade", [HasParent<"DeviceOp">]> { - let summary = "An op to configure the input and output directions of the cascade for a single AIE tile"; - let description = [{ - An operation to configure the cascade on a single tile in both the input and the output - directions. - - Example: - ``` - %tile00 = aie.tile(1, 3) - aie.configure_cascade(%tile00, West, East) - ``` - Configures the input cascade port of %tile00 to the West direction, and the output port to the East direction. - }]; - let arguments = ( - ins Index:$tile, - CascadeDir:$inputDir, - CascadeDir:$outputDir - ); - let results = (outs); - let hasVerifier = 1; - let assemblyFormat = [{ `(` $tile `,` $inputDir `,` $outputDir `)` attr-dict }]; -} - -def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascade_value)> { - let summary = "An op to read from a cascading stream from a neighboring core"; - let description = [{ - An op to read from a cascading stream from a neighboring core. - The result type of this operation must have a size that matches the cascade size, - which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> - }]; - let hasVerifier = 1; - let assemblyFormat = [{ `(` `)` attr-dict `:` type($cascade_value) }]; -} - -def AIE_PutCascadeOp: AIE_Op<"put_cascade", [HasParent<"CoreOp">]> { - let summary = "An op to write to a cascading stream from a neighboring core"; - let description = [{ - An op to write to a cascading stream from a neighboring core. - The argument type of this operation must have a size that matches the cascade size, - which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> - }]; - - let arguments = (ins AnyType:$cascade_value); - let hasVerifier = 1; - let assemblyFormat = [{ `(` $cascade_value `:` type($cascade_value) `)` attr-dict }]; -} +// def AIE_EventOp: AIE_Op<"event", []> { +// let summary = "Event instruction"; +// let description = [{ +// Event instruction. +// }]; +// let arguments = (ins ConfinedAttr, IntMaxValue<1>]>:$val); +// let results = (outs); +// let assemblyFormat = [{ +// `(` $val `)` attr-dict +// }]; +// } +// +// def AIE_GetStreamOp: AIE_Op<"get_stream", [ +// HasParent<"CoreOp"> +// ]>, Results<(outs AnyTypeOf<[F32, I32, I<128>]>)> { +// let summary = "An op to read from a stream channel/port of a switchbox"; +// let description = [{ +// An op to read from a stream channel/port of a switchbox. +// }]; +// +// let arguments = (ins AnyInteger:$channel); +// let results = (outs AnyTypeOf<[F32, I32, I<128>]>:$stream_value); +// +// let assemblyFormat = [{ +// `(` $channel `:` type($channel) `)` attr-dict `:` type($stream_value) +// }]; +// +// let extraClassDeclaration = [{ +// bool isWideStream() { return getStreamValue().getType().isInteger(128); } +// bool isFloatStream() { +// return llvm::isa(getStreamValue().getType()); +// } +// }]; +// } +// +// def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { +// let summary = "An op to write to a stream channel/port of a switchbox"; +// let description = [{ +// An op to write to a stream channel/port of a switchbox. +// }]; +// +// let arguments = ( +// ins AnyInteger:$channel, +// AnyTypeOf<[F32, I32, I<128>]>:$stream_value +// ); +// +// let assemblyFormat = [{ +// `(` $channel `:` type($channel) `,` $stream_value `:` type($stream_value) `)` attr-dict +// }]; +// +// let extraClassDeclaration = [{ +// bool isWideStream() { return getStreamValue().getType().isInteger(128); } +// bool isFloatStream() { +// return llvm::isa(getStreamValue().getType()); +// } +// }]; +// } +// +// def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { +// let arguments = ( +// ins Index:$source_tile, +// Index:$dest_tile +// ); +// let summary = "A cascade connection between tiles"; +// let description = [{ +// The `aie.cascade_flow` operation represents a cascade connection between two `aie.tile` operations. +// During lowering, this is replaced by `aie.configure_cascade` operations for each `aie.tile` based on +// their relative placement to one another. +// +// Example: +// ``` +// %tile03 = aie.tile(0, 3) +// %tile13 = aie.tile(1, 3) +// aie.cascade_flow(%tile03, %tile13) +// ``` +// }]; +// let hasVerifier = 1; +// let assemblyFormat = [{ +// `(` $source_tile `,` $dest_tile `)` attr-dict +// }]; +// let extraClassDeclaration = [{ +// TileOp getSourceTileOp(); +// TileOp getDestTileOp(); +// }]; +// } +// +// def AIE_ConfigureCascadeOp: AIE_Op<"configure_cascade", [HasParent<"DeviceOp">]> { +// let summary = "An op to configure the input and output directions of the cascade for a single AIE tile"; +// let description = [{ +// An operation to configure the cascade on a single tile in both the input and the output +// directions. +// +// Example: +// ``` +// %tile00 = aie.tile(1, 3) +// aie.configure_cascade(%tile00, West, East) +// ``` +// Configures the input cascade port of %tile00 to the West direction, and the output port to the East direction. +// }]; +// let arguments = ( +// ins Index:$tile, +// CascadeDir:$inputDir, +// CascadeDir:$outputDir +// ); +// let results = (outs); +// let hasVerifier = 1; +// let assemblyFormat = [{ `(` $tile `,` $inputDir `,` $outputDir `)` attr-dict }]; +// } +// +// def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascade_value)> { +// let summary = "An op to read from a cascading stream from a neighboring core"; +// let description = [{ +// An op to read from a cascading stream from a neighboring core. +// The result type of this operation must have a size that matches the cascade size, +// which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> +// }]; +// let hasVerifier = 1; +// let assemblyFormat = [{ `(` `)` attr-dict `:` type($cascade_value) }]; +// } +// +// def AIE_PutCascadeOp: AIE_Op<"put_cascade", [HasParent<"CoreOp">]> { +// let summary = "An op to write to a cascading stream from a neighboring core"; +// let description = [{ +// An op to write to a cascading stream from a neighboring core. +// The argument type of this operation must have a size that matches the cascade size, +// which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> +// }]; +// +// let arguments = (ins AnyType:$cascade_value); +// let hasVerifier = 1; +// let assemblyFormat = [{ `(` $cascade_value `:` type($cascade_value) `)` attr-dict }]; +// } def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp">]> { let summary = "Runtime allocation information for a single shim DMA"; @@ -1654,24 +1403,6 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] let hasVerifier = 1; - let extraClassDeclaration = [{ - int size(int index = 0) { - if (llvm::isa(getElemNumber())) - return llvm::dyn_cast( - llvm::dyn_cast(getElemNumber())[index]) - .getInt(); - else - return llvm::dyn_cast(getElemNumber()).getInt(); - } - - TileOp getProducerTileOp(); - - mlir::StringAttr name() { - return getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName()); - } - }]; - let builders = [ OpBuilder<(ins "mlir::StringAttr":$sym_name, "mlir::Value":$producerTile, "mlir::ValueRange":$consumerTiles, "mlir::Attribute":$elemNumber, "mlir::Type":$elem_type, @@ -1727,21 +1458,6 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - std::vector getInputObjectFifos(); - std::vector getOutputObjectFifos(); - - bool isJoin() { - return getFifoIns().size() > 1; - } - - bool isDistribute() { - return getFifoOuts().size() > 1; - } - - std::optional getOptionalSharedTile(); - }]; } def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_external_buffers", [ @@ -1778,8 +1494,6 @@ def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_externa let hasVerifier = 1; let extraClassDeclaration = [{ - TileOp getTileOp(); - ObjectFifoCreateOp getObjectFifo(); // No results so just use default impl. using ::mlir::OpAsmOpInterface::Trait::getAsmResultNames; }]; @@ -1821,11 +1535,6 @@ def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - ObjectFifoCreateOp getObjectFifo(); - int acqNumber() { return getSize(); } - }]; } def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { @@ -1855,11 +1564,6 @@ def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - ObjectFifoCreateOp getObjectFifo(); - int relNumber() { return getSize(); } - }]; } def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { @@ -1896,75 +1600,75 @@ def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { ]; } -def AIE_ObjectFifoRegisterProcessOp: AIE_Op<"objectfifo.register_process", []> { - let summary = "Operation that produces the acquire/release patterns for a process registered to an objectFifo"; - let description = [{ - The `aie.registerProcess` operation allows the user to register a function to an `objectFifo` along with its - acquire and release patterns. These patterns will be used to generate a sequence of acquires and releases - on the `objectFifo` elements. This generated sequence is often in the form of a for loop, however, in the case - of cyclo-static patterns only the repetition of same number accesses and releases will generate a for loop. - This may result in multiple for loops of different sizes being generated. If there is no repetition, then no - loops will be generated. - - Example: - ``` - aie.objectfifo @of1 (%t72, %t73, 2) : !aie.objectfifo> - %length = arith.constant 10 : index - %acquirePatternProducer = arith.constant dense<[1, 2, 2, 0]> : tensor<4xi32> - %releasePatternProducer = arith.constant dense<[0, 1, 1, 2]> : tensor<4xi32> - func @producer_work(%input : !aie.objectfifosubview>) -> () { ... } - - aie.objectfifo.register_process @of1 (Produce, %acquirePatternProducer : tensor<4xi32>, %releasePatternProducer : tensor<4xi32>, @producer_work, %length) - ``` - This operation registers function @producer_work and associated patterns to the produce end of @of1. - @producer_work will be called with the subviews produced when acquiring elements from @of1 following the acquire pattern. - - If the input patterns are static (only one element) then the length of the produced for loop will be that of the input `%length`. - If the input patterns are cyclo-static then they must be of the same size. - }]; - - let arguments = ( - ins ObjectFifoPort:$port, - FlatSymbolRefAttr:$objFifo_name, - I32Tensor:$acquirePatternTensor, - I32Tensor:$releasePatternTensor, - FlatSymbolRefAttr:$callee, - Index:$length - ); - - let assemblyFormat = [{ - attr-dict $objFifo_name `(` - $port `,` - $acquirePatternTensor `:` type($acquirePatternTensor) `,` - $releasePatternTensor `:` type($releasePatternTensor) `,` - $callee `,` $length - `)` - }]; - - let hasVerifier = 1; - - let extraClassDeclaration = [{ - ObjectFifoCreateOp getObjectFifo(); - - mlir::DenseIntElementsAttr getAcquirePattern() { - return llvm::cast(getAcquirePatternTensor() - .getDefiningOp() - .getValue()); - } - - mlir::DenseIntElementsAttr getReleasePattern() { - return llvm::cast(getReleasePatternTensor() - .getDefiningOp() - .getValue()); - } - - int getProcessLength() { - return llvm::cast(getLength() - .getDefiningOp() - .getValue()) - .getInt(); - } - }]; -} +// def AIE_ObjectFifoRegisterProcessOp: AIE_Op<"objectfifo.register_process", []> { +// let summary = "Operation that produces the acquire/release patterns for a process registered to an objectFifo"; +// let description = [{ +// The `aie.registerProcess` operation allows the user to register a function to an `objectFifo` along with its +// acquire and release patterns. These patterns will be used to generate a sequence of acquires and releases +// on the `objectFifo` elements. This generated sequence is often in the form of a for loop, however, in the case +// of cyclo-static patterns only the repetition of same number accesses and releases will generate a for loop. +// This may result in multiple for loops of different sizes being generated. If there is no repetition, then no +// loops will be generated. +// +// Example: +// ``` +// aie.objectfifo @of1 (%t72, %t73, 2) : !aie.objectfifo> +// %length = arith.constant 10 : index +// %acquirePatternProducer = arith.constant dense<[1, 2, 2, 0]> : tensor<4xi32> +// %releasePatternProducer = arith.constant dense<[0, 1, 1, 2]> : tensor<4xi32> +// func @producer_work(%input : !aie.objectfifosubview>) -> () { ... } +// +// aie.objectfifo.register_process @of1 (Produce, %acquirePatternProducer : tensor<4xi32>, %releasePatternProducer : tensor<4xi32>, @producer_work, %length) +// ``` +// This operation registers function @producer_work and associated patterns to the produce end of @of1. +// @producer_work will be called with the subviews produced when acquiring elements from @of1 following the acquire pattern. +// +// If the input patterns are static (only one element) then the length of the produced for loop will be that of the input `%length`. +// If the input patterns are cyclo-static then they must be of the same size. +// }]; +// +// let arguments = ( +// ins ObjectFifoPort:$port, +// FlatSymbolRefAttr:$objFifo_name, +// I32Tensor:$acquirePatternTensor, +// I32Tensor:$releasePatternTensor, +// FlatSymbolRefAttr:$callee, +// Index:$length +// ); +// +// let assemblyFormat = [{ +// attr-dict $objFifo_name `(` +// $port `,` +// $acquirePatternTensor `:` type($acquirePatternTensor) `,` +// $releasePatternTensor `:` type($releasePatternTensor) `,` +// $callee `,` $length +// `)` +// }]; +// +// let hasVerifier = 1; +// +// let extraClassDeclaration = [{ +// ObjectFifoCreateOp getObjectFifo(); +// +// mlir::DenseIntElementsAttr getAcquirePattern() { +// return llvm::cast(getAcquirePatternTensor() +// .getDefiningOp() +// .getValue()); +// } +// +// mlir::DenseIntElementsAttr getReleasePattern() { +// return llvm::cast(getReleasePatternTensor() +// .getDefiningOp() +// .getValue()); +// } +// +// int getProcessLength() { +// return llvm::cast(getLength() +// .getDefiningOp() +// .getValue()) +// .getInt(); +// } +// }]; +// } #endif // AIE_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp b/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp deleted file mode 100644 index 0f9d4e48b..000000000 --- a/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.cpp +++ /dev/null @@ -1,709 +0,0 @@ -//===- AIETargetModel.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 -// -// (c) Copyright 2019 Xilinx Inc. -// (c) Copyright 2023 Advanced Micro Devices, Inc. -// -//===----------------------------------------------------------------------===// - -#include "AIETargetModel.h" -#include "llvm/ADT/SmallSet.h" - -using namespace llvm; - -namespace xilinx { -namespace AIE { -AIETargetModel::~AIETargetModel() = default; - -/// -/// AIE1 TargetModel -/// - -AIEArch AIE1TargetModel::getTargetArch() const { return AIEArch::AIE1; } - -// Return the tile ID of the memory to the west of the given tile, if it exists. -std::optional AIE1TargetModel::getMemWest(TileID src) const { - bool isEvenRow = ((src.row % 2) == 0); - std::optional ret; - if (isEvenRow) - ret = src; - else - ret = {src.col - 1, src.row}; - if (!isValidTile(*ret)) - ret.reset(); - return ret; -} - -// Return the tile ID of the memory to the west of the given tile, if it exists. -std::optional AIE1TargetModel::getMemEast(TileID src) const { - bool isEvenRow = (src.row % 2) == 0; - std::optional ret; - if (isEvenRow) - ret = {src.col + 1, src.row}; - else - ret = src; - if (!isValidTile(*ret)) - ret.reset(); - return ret; -} - -// Return the tile ID of the memory to the west of the given tile, if it exists. -std::optional AIE1TargetModel::getMemNorth(TileID src) const { - std::optional ret({src.col, src.row + 1}); - if (!isValidTile(*ret)) - ret.reset(); - return ret; -} - -std::optional AIE1TargetModel::getMemSouth(TileID src) const { - std::optional ret({src.col, src.row - 1}); - // The first row doesn't have a tile memory south - if (!isValidTile(*ret) || ret->row == 0) - ret.reset(); - return ret; -} - -bool AIE1TargetModel::isMemWest(int srcCol, int srcRow, int dstCol, - int dstRow) const { - bool IsEvenRow = (srcRow % 2) == 0; - return (IsEvenRow && isInternal(srcCol, srcRow, dstCol, dstRow)) || - (!IsEvenRow && isWest(srcCol, srcRow, dstCol, dstRow)); -} - -bool AIE1TargetModel::isMemEast(int srcCol, int srcRow, int dstCol, - int dstRow) const { - bool IsEvenRow = (srcRow % 2) == 0; - return (!IsEvenRow && isInternal(srcCol, srcRow, dstCol, dstRow)) || - (IsEvenRow && isEast(srcCol, srcRow, dstCol, dstRow)); -} - -bool AIE1TargetModel::isMemNorth(int srcCol, int srcRow, int dstCol, - int dstRow) const { - return isNorth(srcCol, srcRow, dstCol, dstRow); -} - -bool AIE1TargetModel::isMemSouth(int srcCol, int srcRow, int dstCol, - int dstRow) const { - return isSouth(srcCol, srcRow, dstCol, dstRow); -} - -bool AIE1TargetModel::isLegalMemAffinity(int coreCol, int coreRow, int memCol, - int memRow) const { - bool IsEvenRow = ((coreRow % 2) == 0); - - bool IsMemWest = (isWest(coreCol, coreRow, memCol, memRow) && !IsEvenRow) || - (isInternal(coreCol, coreRow, memCol, memRow) && IsEvenRow); - - bool IsMemEast = (isEast(coreCol, coreRow, memCol, memRow) && IsEvenRow) || - (isInternal(coreCol, coreRow, memCol, memRow) && !IsEvenRow); - - bool IsMemNorth = isNorth(coreCol, coreRow, memCol, memRow); - bool IsMemSouth = isSouth(coreCol, coreRow, memCol, memRow); - - return IsMemSouth || IsMemNorth || IsMemWest || IsMemEast; -} - -uint32_t -AIE1TargetModel::getNumDestSwitchboxConnections(int col, int row, - WireBundle bundle) const { - if (isShimNOCTile(col, row) || isShimPLTile(col, row)) - switch (bundle) { - case WireBundle::FIFO: - return 2; - case WireBundle::North: - return 6; - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 6; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Ctrl: - return isShimNOCTile(col, row) ? 1 : 0; - default: - return 0; - } - - switch (bundle) { - case WireBundle::Core: - case WireBundle::DMA: - case WireBundle::FIFO: - return 2; - case WireBundle::North: { - if (row == rows() - 1) - return 0; - return 6; - } - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 4; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Ctrl: - return 1; - default: - return 0; - } -} - -uint32_t -AIE1TargetModel::getNumSourceSwitchboxConnections(int col, int row, - WireBundle bundle) const { - if (isShimNOCTile(col, row) || isShimPLTile(col, row)) - switch (bundle) { - case WireBundle::FIFO: - return 2; - case WireBundle::North: - return 4; - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 8; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Trace: - return 1; - case WireBundle::Ctrl: - return isShimNOCTile(col, row) ? 1 : 0; - default: - return 0; - } - - switch (bundle) { - case WireBundle::Core: - case WireBundle::DMA: - case WireBundle::FIFO: - return 2; - case WireBundle::North: { - if (row == rows() - 1) - return 0; - return 4; - } - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 6; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Trace: - return 2; - case WireBundle::Ctrl: - return 1; - default: - return 0; - } -} -uint32_t -AIE1TargetModel::getNumDestShimMuxConnections(int col, int row, - WireBundle bundle) const { - if (isShimNOCorPLTile(col, row)) - switch (bundle) { - case WireBundle::DMA: - return 2; - case WireBundle::NOC: - return 4; - case WireBundle::PLIO: - return 6; - case WireBundle::South: - return 8; // Connection to the south port of the stream switch - default: - return 0; - } - return 0; -} -uint32_t -AIE1TargetModel::getNumSourceShimMuxConnections(int col, int row, - WireBundle bundle) const { - if (isShimNOCorPLTile(col, row)) - switch (bundle) { - case WireBundle::DMA: - return 2; - case WireBundle::NOC: - return 4; - case WireBundle::PLIO: - return 8; - case WireBundle::South: - return 6; // Connection to the south port of the stream switch - default: - return 0; - } - return 0; -} - -bool AIE1TargetModel::isLegalTileConnection(int col, int row, - WireBundle srcBundle, int srcChan, - WireBundle dstBundle, - int dstChan) const { - // Check Channel Id within the range - if (srcChan >= int(getNumSourceSwitchboxConnections(col, row, srcBundle))) - return false; - if (dstChan >= int(getNumDestSwitchboxConnections(col, row, dstBundle))) - return false; - - // Memtile - if (isMemTile(col, row)) { - return false; - } - // Shimtile - else if (isShimNOCorPLTile(col, row)) { - if (srcBundle == WireBundle::Trace) - return dstBundle == WireBundle::South; - else - return true; - } - // Coretile - else if (isCoreTile(col, row)) { - if (srcBundle == WireBundle::Trace) - return dstBundle == WireBundle::South; - else - return true; - } - return false; -} - -/// -/// AIE2 TargetModel -/// - -AIEArch AIE2TargetModel::getTargetArch() const { return AIEArch::AIE2; } - -// Return the tile ID of the memory to the west of the given tile, if it exists. -std::optional AIE2TargetModel::getMemWest(TileID src) const { - std::optional ret({src.col - 1, src.row}); - if (!isValidTile(*ret)) - ret.reset(); - return ret; -} - -// Return the tile ID of the memory to the east of the given tile (ie self), if -// it exists. -std::optional AIE2TargetModel::getMemEast(TileID src) const { - std::optional ret = src; - if (!isValidTile(*ret)) - ret.reset(); - return ret; -} - -// Return the tile ID of the memory to the north of the given tile, if it -// exists. -std::optional AIE2TargetModel::getMemNorth(TileID src) const { - std::optional ret({src.col, src.row + 1}); - if (!isValidTile(*ret)) - ret.reset(); - return ret; -} - -std::optional AIE2TargetModel::getMemSouth(TileID src) const { - std::optional ret({src.col, src.row - 1}); - // The first row doesn't have a tile memory south - // Memtiles don't have memory adjacency to neighboring core tiles. - if (!isValidTile(*ret) || ret->row == 0 || isMemTile(ret->col, ret->row)) - ret.reset(); - return ret; -} - -bool AIE2TargetModel::isMemWest(int srcCol, int srcRow, int dstCol, - int dstRow) const { - return isWest(srcCol, srcRow, dstCol, dstRow); -} - -bool AIE2TargetModel::isMemEast(int srcCol, int srcRow, int dstCol, - int dstRow) const { - return isInternal(srcCol, srcRow, dstCol, dstRow); -} - -bool AIE2TargetModel::isMemNorth(int srcCol, int srcRow, int dstCol, - int dstRow) const { - return isNorth(srcCol, srcRow, dstCol, dstRow); -} - -bool AIE2TargetModel::isMemSouth(int srcCol, int srcRow, int dstCol, - int dstRow) const { - return isSouth(srcCol, srcRow, dstCol, dstRow); -} - -bool AIE2TargetModel::isLegalMemAffinity(int coreCol, int coreRow, int memCol, - int memRow) const { - - bool IsMemWest = isMemWest(coreCol, coreRow, memCol, memRow); - bool IsMemEast = isMemEast(coreCol, coreRow, memCol, memRow); - bool IsMemNorth = isMemNorth(coreCol, coreRow, memCol, memRow); - bool IsMemSouth = isMemSouth(coreCol, coreRow, memCol, memRow); - - if (isMemTile(coreCol, coreRow)) - return isEast(coreCol, coreRow, memCol, memRow) || - isInternal(coreCol, coreRow, memCol, memRow) || - isWest(coreCol, coreRow, memCol, memRow); - return (IsMemSouth && !isMemTile(memCol, memRow)) || IsMemNorth || - IsMemWest || IsMemEast; -} - -uint32_t -AIE2TargetModel::getNumDestSwitchboxConnections(int col, int row, - WireBundle bundle) const { - if (isMemTile(col, row)) - switch (bundle) { - case WireBundle::DMA: - case WireBundle::North: - return 6; - case WireBundle::South: - return 4; - case WireBundle::Ctrl: - return 1; - default: - return 0; - } - - if (isShimNOCTile(col, row) || isShimPLTile(col, row)) - switch (bundle) { - case WireBundle::FIFO: - return 1; - case WireBundle::North: - return 6; - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 6; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Ctrl: - return isShimNOCTile(col, row) ? 1 : 0; - default: - return 0; - } - - switch (bundle) { - case WireBundle::Core: - return 1; - case WireBundle::DMA: - return 2; - case WireBundle::FIFO: - return 1; - case WireBundle::North: { - if (row == rows() - 1) - return 0; - return 6; - } - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 4; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Ctrl: - return 1; - default: - return 0; - } -} - -uint32_t -AIE2TargetModel::getNumSourceSwitchboxConnections(int col, int row, - WireBundle bundle) const { - if (isMemTile(col, row)) - switch (bundle) { - case WireBundle::DMA: - return 6; - case WireBundle::North: - return 4; - case WireBundle::South: - return 6; - case WireBundle::Trace: - case WireBundle::Ctrl: - return 1; - default: - return 0; - } - - if (isShimNOCTile(col, row) || isShimPLTile(col, row)) - switch (bundle) { - case WireBundle::FIFO: - return 1; - case WireBundle::North: - return 4; - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 8; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Trace: - return 1; - case WireBundle::Ctrl: - return isShimNOCTile(col, row) ? 1 : 0; - default: - return 0; - } - - // compute/core tile - switch (bundle) { - case WireBundle::Core: - return 1; - case WireBundle::DMA: - return 2; - case WireBundle::FIFO: - return 1; - case WireBundle::North: { - if (row == rows() - 1) - return 0; - return 4; - } - case WireBundle::West: { - if (col == 0) - return 0; - return 4; - } - case WireBundle::South: - return 6; - case WireBundle::East: { - if (col == columns() - 1) - return 0; - return 4; - } - case WireBundle::Trace: - // Port 0: core trace. Port 1: memory trace. - return 2; - case WireBundle::Ctrl: - return 1; - default: - return 0; - } -} - -uint32_t -AIE2TargetModel::getNumDestShimMuxConnections(int col, int row, - WireBundle bundle) const { - if (isShimNOCorPLTile(col, row)) - switch (bundle) { - case WireBundle::DMA: - return 2; - case WireBundle::NOC: - return 4; - case WireBundle::PLIO: - return 6; - case WireBundle::South: - return 8; // Connection to the south port of the stream switch - default: - return 0; - } - - return 0; -} - -uint32_t -AIE2TargetModel::getNumSourceShimMuxConnections(int col, int row, - WireBundle bundle) const { - if (isShimNOCorPLTile(col, row)) - switch (bundle) { - case WireBundle::DMA: - return 2; - case WireBundle::NOC: - return 4; - case WireBundle::PLIO: - return 8; - case WireBundle::South: - return 6; // Connection to the south port of the stream switch - default: - return 0; - } - - return 0; -} - -bool AIE2TargetModel::isLegalTileConnection(int col, int row, - WireBundle srcBundle, int srcChan, - WireBundle dstBundle, - int dstChan) const { - // Check Channel Id within the range - if (srcChan >= int(getNumSourceSwitchboxConnections(col, row, srcBundle))) - return false; - if (dstChan >= int(getNumDestSwitchboxConnections(col, row, dstBundle))) - return false; - - // Lambda function to check if a bundle is in a list - auto isBundleInList = [](WireBundle bundle, - std::initializer_list bundles) { - return std::find(bundles.begin(), bundles.end(), bundle) != bundles.end(); - }; - - // Memtile - if (isMemTile(col, row)) { - if (srcBundle == WireBundle::DMA) { - if (dstBundle == WireBundle::DMA) - return srcChan == dstChan; - if (isBundleInList(dstBundle, {WireBundle::Ctrl, WireBundle::South, - WireBundle::North})) - return true; - } - if (srcBundle == WireBundle::Ctrl) { - if (dstBundle == WireBundle::DMA) - return dstChan == 5; - if (isBundleInList(dstBundle, {WireBundle::South, WireBundle::North})) - return true; - } - if (isBundleInList(srcBundle, {WireBundle::South, WireBundle::North})) { - if (isBundleInList(dstBundle, {WireBundle::DMA, WireBundle::Ctrl})) - return true; - if (isBundleInList(dstBundle, {WireBundle::South, WireBundle::North})) - return srcChan == dstChan; - } - if (srcBundle == WireBundle::Trace) { - if (dstBundle == WireBundle::DMA) - return dstChan == 5; - if (dstBundle == WireBundle::South) - return true; - } - } - // Shimtile - else if (isShimNOCorPLTile(col, row)) { - if (srcBundle == WireBundle::Ctrl) - return dstBundle != WireBundle::Ctrl; - if (isBundleInList(srcBundle, {WireBundle::FIFO, WireBundle::South})) - return isBundleInList(dstBundle, {WireBundle::Ctrl, WireBundle::FIFO, - WireBundle::South, WireBundle::West, - WireBundle::North, WireBundle::East}); - if (isBundleInList(srcBundle, - {WireBundle::West, WireBundle::North, WireBundle::East})) - return (srcBundle == dstBundle) - ? (srcChan == dstChan) - : isBundleInList(dstBundle, - {WireBundle::Ctrl, WireBundle::FIFO, - WireBundle::South, WireBundle::West, - WireBundle::North, WireBundle::East}); - if (srcBundle == WireBundle::Trace) { - if (isBundleInList(dstBundle, {WireBundle::FIFO, WireBundle::South})) - return true; - if (isBundleInList(dstBundle, {WireBundle::West, WireBundle::East})) - return dstChan == 0; - } - } - // Coretile - else if (isCoreTile(col, row)) { - if (isBundleInList(srcBundle, - {WireBundle::DMA, WireBundle::FIFO, WireBundle::South, - WireBundle::West, WireBundle::North, WireBundle::East})) - if (isBundleInList(dstBundle, - {WireBundle::Core, WireBundle::DMA, WireBundle::Ctrl, - WireBundle::FIFO, WireBundle::South, WireBundle::West, - WireBundle::North, WireBundle::East})) - return (srcBundle == dstBundle) ? (srcChan == dstChan) : true; - if (srcBundle == WireBundle::Core) - return dstBundle != WireBundle::Core; - if (srcBundle == WireBundle::Ctrl) - return dstBundle != WireBundle::Ctrl && dstBundle != WireBundle::DMA; - if (srcBundle == WireBundle::Trace) { - if (dstBundle == WireBundle::DMA) - return dstChan == 0; - if (isBundleInList(dstBundle, {WireBundle::FIFO, WireBundle::South})) - return true; - } - } - return false; -} - -void AIETargetModel::validate() const { - // Every tile in a shimtile row must be a shimtile, and can only be one type - // of shim tile. - for (int j = 0; j < columns(); j++) { - assert(!isMemTile(j, 0) && (isShimPLTile(j, 0) || isShimNOCTile(j, 0)) && - !isCoreTile(j, 0)); - assert(isShimPLTile(j, 0) ^ isShimNOCTile(j, 0)); - } - - // Every tile in a memtile row must be a memtile. - for (int i = 1; i < 1 + static_cast(getNumMemTileRows()); i++) - for (int j = 0; j < columns(); j++) - assert(isMemTile(j, i) && !isShimPLTile(j, i) && !isShimNOCTile(j, i) && - !isCoreTile(j, i)); - - // Every other tile is a coretile. - for (int i = 1 + getNumMemTileRows(); i < rows(); i++) - for (int j = 0; j < columns(); j++) - assert(!isMemTile(j, i) && !isShimPLTile(j, i) && !isShimNOCTile(j, i) && - isCoreTile(j, i)); - - // Looking North, buses must match - for (int i = 0; i < rows() - 1; i++) - for (int j = 0; j < columns(); j++) - assert(getNumSourceSwitchboxConnections(j, i, WireBundle::North) == - getNumDestSwitchboxConnections(j, i + 1, WireBundle::South)); - // Looking South, buses must match - for (int i = 1; i < rows(); i++) - for (int j = 0; j < columns(); j++) - assert(getNumSourceSwitchboxConnections(j, i, WireBundle::South) == - getNumDestSwitchboxConnections(j, i - 1, WireBundle::North)); - // Looking East, buses must match - for (int i = 0; i < rows(); i++) - for (int j = 0; j < columns() - 1; j++) - assert(getNumSourceSwitchboxConnections(j, i, WireBundle::East) == - getNumDestSwitchboxConnections(j + 1, i, WireBundle::West)); - // Looking West, buses must match - for (int i = 0; i < rows(); i++) - for (int j = 1; j < columns(); j++) - assert(getNumSourceSwitchboxConnections(j, i, WireBundle::West) == - getNumDestSwitchboxConnections(j - 1, i, WireBundle::East)); - // Edges have no connections - for (int j = 0; j < columns(); j++) - assert(getNumSourceSwitchboxConnections(j, rows() - 1, WireBundle::North) == - 0); - for (int i = 0; i < rows(); i++) - assert(getNumSourceSwitchboxConnections(columns() - 1, i, - WireBundle::East) == 0); - for (int i = 0; i < rows(); i++) - assert(getNumSourceSwitchboxConnections(0, i, WireBundle::West) == 0); - - // FIFOS are consistent - for (int i = 0; i < rows(); i++) - for (int j = 0; j < columns(); j++) - assert(getNumSourceSwitchboxConnections(j, i, WireBundle::FIFO) == - getNumDestSwitchboxConnections(j, i, WireBundle::FIFO)); -} - -} // namespace AIE -} // namespace xilinx diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h b/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h deleted file mode 100644 index ad8161c0a..000000000 --- a/compiler/plugins/target/AMD-AIE/aie/AIETargetModel.h +++ /dev/null @@ -1,529 +0,0 @@ -//===- AIETargetModel.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 2023 Advanced Micro Devices, Inc. -// -//===----------------------------------------------------------------------===// - -#ifndef MLIR_AIE_DEVICEMODEL_H -#define MLIR_AIE_DEVICEMODEL_H - -#include "AIEEnums.h" - -#include "llvm/ADT/DenseSet.h" - -#include - -namespace xilinx::AIE { - -using TileID = struct TileID { - // friend definition (will define the function as a non-member function in the - // namespace surrounding the class). - friend std::ostream &operator<<(std::ostream &os, const TileID &s) { - os << "TileID(" << s.col << ", " << s.row << ")"; - return os; - } - - friend std::string to_string(const TileID &s) { - std::ostringstream ss; - ss << s; - return ss.str(); - } - - friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, const TileID &s) { - os << to_string(s); - return os; - } - - // Imposes a lexical order on TileIDs. - inline bool operator<(const TileID &rhs) const { - return std::tie(col, row) < std::tie(rhs.col, rhs.row); - } - - bool operator==(const TileID &rhs) const { - return std::tie(col, row) == std::tie(rhs.col, rhs.row); - } - - bool operator!=(const TileID &rhs) const { return !(*this == rhs); } - - int col, row; -}; - -class AIETargetModel { -public: - AIETargetModel() = default; - - virtual ~AIETargetModel(); - - /// Return the target architecture. - virtual AIEArch getTargetArch() const = 0; - - /// Return the data bus width of the device. - virtual uint32_t getAddressGenGranularity() const = 0; - - /// Return the number of columns in the device. - virtual int columns() const = 0; - - /// Return the number of rows in the device. - virtual int rows() const = 0; - - /// Return true if the given tile is a 'Core' tile. These tiles - /// include a Core, TileDMA, tile memory, and stream connections. - virtual bool isCoreTile(int col, int row) const = 0; - - /// Return true if the given tile is an AIE2 'Memory' tile. These tiles - /// include a TileDMA, tile memory, and stream connections, but no core. - virtual bool isMemTile(int col, int row) const = 0; - - /// Return true if the given tile is a Shim NOC tile. These tiles include a - /// ShimDMA and a connection to the memory-mapped NOC. They do not contain - /// any memory. - virtual bool isShimNOCTile(int col, int row) const = 0; - - /// Return true if the given tile is a Shim PL interface tile. These - /// tiles do not include a ShimDMA and instead include connections to the PL. - /// They do not contain any memory. - virtual bool isShimPLTile(int col, int row) const = 0; - - /// Return true if the given tile is either a Shim NOC or a Shim PL interface - /// tile. - virtual bool isShimNOCorPLTile(int col, int row) const = 0; - - /// Return true if the given tile ID is valid. - virtual bool isValidTile(TileID src) const { - return src.col >= 0 && src.col < columns() && src.row >= 0 && - src.row < rows(); - } - - /// Return the tile ID of the memory to the west of the given tile, if it - /// exists. - virtual std::optional getMemWest(TileID src) const = 0; - /// Return the tile ID of the memory to the east of the given tile, if it - /// exists. - virtual std::optional getMemEast(TileID src) const = 0; - /// Return the tile ID of the memory to the north of the given tile, if it - /// exists. - virtual std::optional getMemNorth(TileID src) const = 0; - /// Return the tile ID of the memory to the south of the given tile, if it - /// exists. - virtual std::optional getMemSouth(TileID src) const = 0; - - /// Return true if src is the internal memory of dst - bool isInternal(int srcCol, int srcRow, int dstCol, int dstRow) const { - return srcCol == dstCol && srcRow == dstRow; - } - - /// Return true if src is West of dst - bool isWest(int srcCol, int srcRow, int dstCol, int dstRow) const { - return srcCol == dstCol + 1 && srcRow == dstRow; - } - - /// Return true if src is East of dst - bool isEast(int srcCol, int srcRow, int dstCol, int dstRow) const { - return srcCol == dstCol - 1 && srcRow == dstRow; - } - - /// Return true if src is North of dst - bool isNorth(int srcCol, int srcRow, int dstCol, int dstRow) const { - return srcCol == dstCol && srcRow == dstRow - 1; - } - - /// Return true if src is South of dst - bool isSouth(int srcCol, int srcRow, int dstCol, int dstRow) const { - return srcCol == dstCol && srcRow == dstRow + 1; - } - - /// Return true if src has a memory tile which is West of dst - virtual bool isMemWest(int srcCol, int srcRow, int dstCol, - int dstRow) const = 0; - /// Return true if src has a memory tile which is East of dst - virtual bool isMemEast(int srcCol, int srcRow, int dstCol, - int dstRow) const = 0; - /// Return true if src has a memory tile which is North of dst - virtual bool isMemNorth(int srcCol, int srcRow, int dstCol, - int dstRow) const = 0; - /// Return true if src has a memory tile which is South of dst - virtual bool isMemSouth(int srcCol, int srcRow, int dstCol, - int dstRow) const = 0; - - /// Return true if core can access the memory in mem - virtual bool isLegalMemAffinity(int coreCol, int coreRow, int memCol, - int memRow) const = 0; - - /// Return the base address in the local address map of different memories. - virtual uint32_t getMemInternalBaseAddress(TileID src) const = 0; - virtual uint32_t getMemSouthBaseAddress() const = 0; - virtual uint32_t getMemWestBaseAddress() const = 0; - virtual uint32_t getMemNorthBaseAddress() const = 0; - virtual uint32_t getMemEastBaseAddress() const = 0; - - /// Return the size (in bytes) of the local data memory of a core. - virtual uint32_t getLocalMemorySize() const = 0; - - /// Return the size (in bits) of the accumulator/cascade. - virtual uint32_t getAccumulatorCascadeSize() const = 0; - - /// Return the number of lock objects - virtual uint32_t getNumLocks(int col, int row) const = 0; - - /// Return the number of buffer descriptors supported by the DMA in the given - /// tile. - virtual uint32_t getNumBDs(int col, int row) const = 0; - - virtual uint32_t getNumMemTileRows() const = 0; - /// Return the size (in bytes) of a MemTile. - virtual uint32_t getMemTileSize() const = 0; - /// Return the number of destinations of connections inside a switchbox. These - /// are the targets of connect operations in the switchbox. - virtual uint32_t getNumDestSwitchboxConnections(int col, int row, - WireBundle bundle) const = 0; - /// Return the number of sources of connections inside a switchbox. These are - /// the origins of connect operations in the switchbox. - virtual uint32_t - getNumSourceSwitchboxConnections(int col, int row, - WireBundle bundle) const = 0; - /// Return the number of destinations of connections inside a shimmux. These - /// are the targets of connect operations in the switchbox. - virtual uint32_t getNumDestShimMuxConnections(int col, int row, - WireBundle bundle) const = 0; - /// Return the number of sources of connections inside a shimmux. These are - /// the origins of connect operations in the switchbox. - virtual uint32_t getNumSourceShimMuxConnections(int col, int row, - WireBundle bundle) const = 0; - - // Return true if the stream switch connection is legal, false otherwise. - virtual bool isLegalTileConnection(int col, int row, WireBundle srcBundle, - int srcChan, WireBundle dstBundle, - int dstChan) const = 0; - - // Run consistency checks on the target model. - void validate() const; - - // Return true if this is an NPU-based device - // There are several special cases for handling the NPU at the moment. - virtual bool isNPU() const { return false; } - - // Return the bit offset of the column within a tile address. - // This is used to compute the control address of a tile from it's column - // location. - virtual uint32_t getColumnShift() const = 0; - - // Return the bit offset of the row within a tile address. - // This is used to compute the control address of a tile from it's row - // location. - virtual uint32_t getRowShift() const = 0; -}; - -class AIE1TargetModel : public AIETargetModel { -public: - AIE1TargetModel() = default; - - bool isCoreTile(int col, int row) const override { return row > 0; } - bool isMemTile(int col, int row) const override { return false; } - - AIEArch getTargetArch() const override; - - std::optional getMemWest(TileID src) const override; - std::optional getMemEast(TileID src) const override; - std::optional getMemNorth(TileID src) const override; - std::optional getMemSouth(TileID src) const override; - - bool isMemWest(int srcCol, int srcRow, int dstCol, int dstRow) const override; - bool isMemEast(int srcCol, int srcRow, int dstCol, int dstRow) const override; - bool isMemNorth(int srcCol, int srcRow, int dstCol, - int dstRow) const override; - bool isMemSouth(int srcCol, int srcRow, int dstCol, - int dstRow) const override; - - bool isLegalMemAffinity(int coreCol, int coreRow, int memCol, - int memRow) const override; - - uint32_t getMemInternalBaseAddress(TileID src) const override { - if (src.row % 2 == 0) - // Internal is West - return getMemWestBaseAddress(); - // Internal is East - return getMemEastBaseAddress(); - } - - uint32_t getMemSouthBaseAddress() const override { return 0x00020000; } - uint32_t getMemWestBaseAddress() const override { return 0x00028000; } - uint32_t getMemNorthBaseAddress() const override { return 0x00030000; } - uint32_t getMemEastBaseAddress() const override { return 0x00038000; } - uint32_t getLocalMemorySize() const override { return 0x00008000; } - uint32_t getAccumulatorCascadeSize() const override { return 384; } - uint32_t getNumLocks(int col, int row) const override { return 16; } - uint32_t getNumBDs(int col, int row) const override { return 16; } - uint32_t getNumMemTileRows() const override { return 0; } - uint32_t getMemTileSize() const override { return 0; } - - uint32_t getNumDestSwitchboxConnections(int col, int row, - WireBundle bundle) const override; - uint32_t getNumSourceSwitchboxConnections(int col, int row, - WireBundle bundle) const override; - uint32_t getNumDestShimMuxConnections(int col, int row, - WireBundle bundle) const override; - uint32_t getNumSourceShimMuxConnections(int col, int row, - WireBundle bundle) const override; - bool isLegalTileConnection(int col, int row, WireBundle srcBundle, - int srcChan, WireBundle dstBundle, - int dstChan) const override; - - uint32_t getColumnShift() const override { return 23; } - uint32_t getRowShift() const override { return 18; } -}; - -class AIE2TargetModel : public AIETargetModel { -public: - AIE2TargetModel() = default; - - AIEArch getTargetArch() const override; - - uint32_t getAddressGenGranularity() const override { return 32; } - - std::optional getMemWest(TileID src) const override; - std::optional getMemEast(TileID src) const override; - std::optional getMemNorth(TileID src) const override; - std::optional getMemSouth(TileID src) const override; - - bool isMemWest(int srcCol, int srcRow, int dstCol, int dstRow) const override; - bool isMemEast(int srcCol, int srcRow, int dstCol, int dstRow) const override; - bool isMemNorth(int srcCol, int srcRow, int dstCol, - int dstRow) const override; - bool isMemSouth(int srcCol, int srcRow, int dstCol, - int dstRow) const override; - - bool isLegalMemAffinity(int coreCol, int coreRow, int memCol, - int memRow) const override; - - uint32_t getMemInternalBaseAddress(TileID src) const override { - return getMemEastBaseAddress(); - } - - uint32_t getMemSouthBaseAddress() const override { return 0x00040000; } - uint32_t getMemWestBaseAddress() const override { return 0x00050000; } - uint32_t getMemNorthBaseAddress() const override { return 0x00060000; } - uint32_t getMemEastBaseAddress() const override { return 0x00070000; } - uint32_t getLocalMemorySize() const override { return 0x00010000; } - uint32_t getAccumulatorCascadeSize() const override { return 512; } - - uint32_t getNumLocks(int col, int row) const override { - return isMemTile(col, row) ? 64 : 16; - } - - uint32_t getNumBDs(int col, int row) const override { - return isMemTile(col, row) ? 48 : 16; - } - - uint32_t getMemTileSize() const override { return 0x00080000; } - - uint32_t getNumDestSwitchboxConnections(int col, int row, - WireBundle bundle) const override; - uint32_t getNumSourceSwitchboxConnections(int col, int row, - WireBundle bundle) const override; - uint32_t getNumDestShimMuxConnections(int col, int row, - WireBundle bundle) const override; - uint32_t getNumSourceShimMuxConnections(int col, int row, - WireBundle bundle) const override; - bool isLegalTileConnection(int col, int row, WireBundle srcBundle, - int srcChan, WireBundle dstBundle, - int dstChan) const override; - - uint32_t getColumnShift() const override { return 25; } - uint32_t getRowShift() const override { return 20; } -}; - -class VC1902TargetModel : public AIE1TargetModel { - llvm::SmallDenseSet nocColumns = { - 2, 3, 6, 7, 10, 11, 18, 19, 26, 27, 34, 35, 42, 43, 46, 47}; - -public: - VC1902TargetModel() = default; - - uint32_t getAddressGenGranularity() const override { return 32; } - - int columns() const override { return 50; } - - int rows() const override { return 9; /* One Shim row and 8 Core rows. */ } - - bool isShimNOCTile(int col, int row) const override { - return row == 0 && nocColumns.contains(col); - } - - bool isShimPLTile(int col, int row) const override { - return row == 0 && !nocColumns.contains(col); - } - - bool isShimNOCorPLTile(int col, int row) const override { - return isShimNOCTile(col, row) || isShimPLTile(col, row); - } -}; - -class VE2302TargetModel : public AIE2TargetModel { - llvm::SmallDenseSet nocColumns = {2, 3, 6, 7, 10, 11}; - -public: - VE2302TargetModel() = default; - - int columns() const override { return 17; } - - int rows() const override { - return 4; /* One Shim row, 1 memtile rows, and 2 Core rows. */ - } - - bool isCoreTile(int col, int row) const override { return row > 1; } - bool isMemTile(int col, int row) const override { return row == 1; } - - bool isShimNOCTile(int col, int row) const override { - return row == 0 && nocColumns.contains(col); - } - - bool isShimPLTile(int col, int row) const override { - return row == 0 && !nocColumns.contains(col); - } - - bool isShimNOCorPLTile(int col, int row) const override { - return isShimNOCTile(col, row) || isShimPLTile(col, row); - } - - uint32_t getNumMemTileRows() const override { return 1; } -}; - -class VE2802TargetModel : public AIE2TargetModel { - llvm::SmallDenseSet nocColumns = {2, 3, 6, 7, 14, 15, - 22, 23, 30, 31, 34, 35}; - -public: - VE2802TargetModel() = default; - - int columns() const override { return 38; } - - int rows() const override { - return 11; /* One Shim row, 2 memtile rows, and 8 Core rows. */ - } - - bool isCoreTile(int col, int row) const override { return row > 2; } - - bool isMemTile(int col, int row) const override { - return row == 1 || row == 2; - } - - bool isShimNOCTile(int col, int row) const override { - return row == 0 && nocColumns.contains(col); - } - - bool isShimPLTile(int col, int row) const override { - return row == 0 && !nocColumns.contains(col); - } - - bool isShimNOCorPLTile(int col, int row) const override { - return isShimNOCTile(col, row) || isShimPLTile(col, row); - } - - uint32_t getNumMemTileRows() const override { return 2; } -}; - -class BaseNPUTargetModel : public AIE2TargetModel { -public: - BaseNPUTargetModel() = default; - - int rows() const override { - return 6; /* 1 Shim row, 1 memtile row, and 4 Core rows. */ - } - - bool isCoreTile(int col, int row) const override { return row > 1; } - bool isMemTile(int col, int row) const override { return row == 1; } - - bool isShimPLTile(int col, int row) const override { - return false; // No PL - } - - bool isShimNOCorPLTile(int col, int row) const override { - return isShimNOCTile(col, row) || isShimPLTile(col, row); - } - - uint32_t getNumMemTileRows() const override { return 1; } - - // Return true if the device model is virtualized. This is used - // during CDO code generation to configure aie-rt properly. - virtual bool isVirtualized() const = 0; - - virtual bool isNPU() const override { return true; } -}; - -// The full Phoenix NPU -class NPUTargetModel : public BaseNPUTargetModel { -public: - NPUTargetModel() = default; - - int columns() const override { return 5; } - - bool isShimNOCTile(int col, int row) const override { - return row == 0 && col > 0; - } - - bool isShimPLTile(int col, int row) const override { - // This isn't useful because it's not connected to anything. - return row == 0 && col == 0; - } - - bool isVirtualized() const override { return false; } -}; - -// A sub-portion of the NPU -class VirtualizedNPUTargetModel : public BaseNPUTargetModel { - int cols; - -public: - VirtualizedNPUTargetModel(int _cols) : cols(_cols) {} - - uint32_t getAddressGenGranularity() const override { return 32; } - - int columns() const override { return cols; } - - bool isShimNOCTile(int col, int row) const override { return row == 0; } - - bool isVirtualized() const override { return true; } -}; - -} // namespace xilinx::AIE - -namespace llvm { -template <> -struct DenseMapInfo { - using FirstInfo = DenseMapInfo; - using SecondInfo = DenseMapInfo; - - static xilinx::AIE::TileID getEmptyKey() { - return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; - } - - static xilinx::AIE::TileID getTombstoneKey() { - return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; - } - - static unsigned getHashValue(const xilinx::AIE::TileID &t) { - return detail::combineHashValue(FirstInfo::getHashValue(t.col), - SecondInfo::getHashValue(t.row)); - } - - static bool isEqual(const xilinx::AIE::TileID &lhs, - const xilinx::AIE::TileID &rhs) { - return lhs == rhs; - } -}; -} // namespace llvm - -template <> -struct std::hash { - std::size_t operator()(const xilinx::AIE::TileID &s) const noexcept { - std::size_t h1 = std::hash{}(s.col); - std::size_t h2 = std::hash{}(s.row); - return h1 ^ (h2 << 1); - } -}; - -#endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp index 5ce3c9f1c..2beb30db2 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp @@ -7,8 +7,8 @@ #include #include -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/STLExtras.h" #include "mlir/Analysis/TopologicalSortUtils.h" @@ -52,18 +52,101 @@ using xilinx::AIE::ObjectFifoRegisterExternalBuffersOp; using xilinx::AIE::ObjectFifoReleaseOp; using xilinx::AIE::ObjectFifoSubviewAccessOp; using xilinx::AIE::ShimDMAAllocationOp; -using xilinx::AIE::ShimDMAOp; using xilinx::AIE::TileOp; using xilinx::AIE::UseLockOp; using xilinx::AIE::WireBundle; +namespace { +std::vector getInputObjectFifos(ObjectFifoLinkOp &op) { + std::vector inputObjFifos; + Operation *parent = op.getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + for (auto sym : op.getFifoIns()) { + auto name = dyn_cast(sym); + if (auto *st = SymbolTable::lookupSymbolIn(parent, name); + isa_and_nonnull(st)) + inputObjFifos.push_back(dyn_cast(st)); + } + } + } + return inputObjFifos; +} + +std::vector getOutputObjectFifos(ObjectFifoLinkOp &op) { + std::vector outputObjFifos; + Operation *parent = op.getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + for (auto sym : op.getFifoOuts()) { + auto name = dyn_cast(sym); + if (auto *st = SymbolTable::lookupSymbolIn(parent, name); + isa_and_nonnull(st)) + outputObjFifos.push_back(dyn_cast(st)); + } + } + } + return outputObjFifos; +} + +int objFifoSize(ObjectFifoCreateOp op, int index = 0) { + if (llvm::isa(op.getElemNumber())) + return llvm::dyn_cast( + llvm::dyn_cast(op.getElemNumber())[index]) + .getInt(); + else + return llvm::dyn_cast(op.getElemNumber()).getInt(); +} + +template +ObjectFifoCreateOp getObjectFifo(T op) { + Operation *parent = op.getOperation(); + while ((parent = parent->getParentOp())) { + if (parent->hasTrait()) { + if (auto *st = SymbolTable::lookupSymbolIn(parent, op.getObjFifoName()); + isa_and_nonnull(st)) + return dyn_cast(st); + } + } + return {}; +} + +bool isJoin(ObjectFifoLinkOp op) { return op.getFifoIns().size() > 1; } + +bool isDistribute(ObjectFifoLinkOp op) { return op.getFifoOuts().size() > 1; } + +std::optional getOptionalSharedTile(ObjectFifoLinkOp op) { + if (isJoin(op)) { + auto fifoOut = getOutputObjectFifos(op)[0]; + for (auto fifoIn : getInputObjectFifos(op)) + if (fifoOut.getProducerTile() != fifoIn.getConsumerTiles()[0]) return {}; + return {fifoOut.getProducerTile()}; + } + + if (isDistribute(op)) { + auto fifoIn = getInputObjectFifos(op)[0]; + for (auto fifoOut : getOutputObjectFifos(op)) + if (fifoIn.getConsumerTiles()[0] != fifoOut.getProducerTile()) return {}; + return {fifoIn.getConsumerTiles()[0]}; + } + + auto fifoIn = getInputObjectFifos(op); + if (auto fifoOut = getOutputObjectFifos(op); + !fifoIn.empty() && !fifoOut.empty()) + for (auto consumerIn : fifoIn[0].getConsumerTiles()) + if (consumerIn == fifoOut[0].getProducerTile()) + return {fifoOut[0].getProducerTile()}; + return {}; +} +} // namespace + class LockAnalysis { DenseMap, int> locksPerTile; public: LockAnalysis(DeviceOp &device) { for (auto lockOp : device.getOps()) - locksPerTile[{lockOp.getTile(), lockOp.getLockIDValue()}] = 1; + locksPerTile[{lockOp.getTile(), lockOp.getLockID().value()}] = 1; } /// Given a tile, returns next usable lockID for that tile. @@ -122,9 +205,9 @@ enum SharedMemoryDirection { LHS = -1, RHS = 1, NONE = 0 }; std::optional getOptionalLinkOp(ObjectFifoCreateOp op) { auto device = op->getParentOfType(); for (ObjectFifoLinkOp linkOp : device.getOps()) { - for (ObjectFifoCreateOp in : linkOp.getInputObjectFifos()) + for (ObjectFifoCreateOp in : getInputObjectFifos(linkOp)) if (in == op) return {linkOp}; - for (ObjectFifoCreateOp out : linkOp.getOutputObjectFifos()) + for (ObjectFifoCreateOp out : getOutputObjectFifos(linkOp)) if (out == op) return {linkOp}; } return {}; @@ -175,13 +258,14 @@ bool requiresDMAs(ObjectFifoCreateOp createOp, for (auto consumerTile : createOp.getConsumerTiles()) { auto consumerTileOp = dyn_cast(consumerTile.getDefiningOp()); if (!consumerTileOp) continue; + TileOp producerTileOp = + cast(createOp.getProducerTile().getDefiningOp()); if (std::count(splitBecauseLink.begin(), splitBecauseLink.end(), createOp)) - shareDirection = haveSharedMemory(createOp.getProducerTileOp(), - createOp.getProducerTileOp()); + // TODO(max): wut + shareDirection = haveSharedMemory(producerTileOp, producerTileOp); else - shareDirection = - haveSharedMemory(createOp.getProducerTileOp(), consumerTileOp); + shareDirection = haveSharedMemory(producerTileOp, consumerTileOp); } if (shareDirection == LHS || shareDirection == RHS) { @@ -210,31 +294,31 @@ bool requiresDMAs(ObjectFifoCreateOp createOp, /// return 0. int findObjectFifoSize(DeviceOp &device, Value tile, ObjectFifoCreateOp objFifo) { - if (objFifo.size() == 0) return 0; + if (objFifoSize(objFifo) == 0) return 0; AMDAIEDeviceModel deviceModel = getDeviceModel(static_cast(device.getDevice())); // if memTile, size is equal to objFifo size TileOp tileOp = tile.getDefiningOp(); if (deviceModel.isMemTile(tileOp.getCol(), tileOp.getRow())) - return objFifo.size(); + return objFifoSize(objFifo); int maxAcquire = 0; for (auto coreOp : make_filter_range( device.getOps(), [&tile](auto coreOp) { return coreOp.getTile() == tile; })) coreOp.walk([&](ObjectFifoAcquireOp acqOp) { - if (acqOp.getObjectFifo() == objFifo && acqOp.acqNumber() > maxAcquire) - maxAcquire = acqOp.acqNumber(); + if (getObjectFifo(acqOp) == objFifo && acqOp.getSize() > maxAcquire) + maxAcquire = acqOp.getSize(); }); - if (maxAcquire == 1 && objFifo.size() == 1) return 1; + if (maxAcquire == 1 && objFifoSize(objFifo) == 1) return 1; // +1 because objectFifo size is always 1 bigger than maxAcquire to allow // for prefetching: simplest case scenario is at least a ping-pong buffer if (maxAcquire > 0) return maxAcquire + 1; - return objFifo.size(); + return objFifoSize(objFifo); } /// Translate ObjectFifoCreateOp to corresponding DMABD, UseLocks, and NextBDs. @@ -256,7 +340,7 @@ void createDMA( } // if none exists, create one - TileOp objFifoTileOp = target.getProducerTileOp(); + TileOp objFifoTileOp = cast(target.getProducerTile().getDefiningOp()); if (!producer) { if (device->getNumRegions() != 1) llvm::report_fatal_error("expected num regions for device op"); @@ -333,7 +417,7 @@ void createAMDAIETileDMA( const DenseMap &objFifoLinks, const DenseMap> &buffersPerFifo, const DenseMap> &locksPerFifo) { - size_t numBlocks = createOp.size(); + size_t numBlocks = objFifoSize(createOp); if (numBlocks == 0) return; // search for the buffers/locks (based on if this objFifo has a link) ObjectFifoCreateOp target = createOp; @@ -359,7 +443,7 @@ void createMemTileDMA( const DenseMap &objFifoLinks, const DenseMap> &buffersPerFifo, const DenseMap> &locksPerFifo) { - size_t numBlocks = createOp.size(); + size_t numBlocks = objFifoSize(createOp); if (numBlocks == 0) return; auto fifo = llvm::cast(createOp.getElemType()); @@ -382,7 +466,7 @@ void createMemTileDMA( for (auto fifoIn : fifos) { auto fifoType = llvm::cast(fifoIn.getElemType()); auto fifoElemType = llvm::cast(fifoType.getElementType()); - if (fifoIn.name() == createOp.name()) break; + if (name(fifoIn) == name(createOp)) break; extraOffset += fifoElemType.getNumElements(); } }; @@ -392,13 +476,13 @@ void createMemTileDMA( if (auto linkOp = getOptionalLinkOp(createOp); objFifoLinks.contains(*linkOp)) { target = objFifoLinks.at(*linkOp); - if (linkOp->isJoin()) { + if (isJoin(*linkOp)) { // find offset based on order of this op in join list - getExtraOffset(*linkOp, linkOp->getInputObjectFifos(), + getExtraOffset(*linkOp, getInputObjectFifos(*linkOp), linkOp->getFifoIns().size()); - } else if (linkOp->isDistribute()) { + } else if (isDistribute(*linkOp)) { // find offset based on order of this op in distribute list - getExtraOffset(*linkOp, linkOp->getOutputObjectFifos(), + getExtraOffset(*linkOp, getOutputObjectFifos(*linkOp), linkOp->getFifoOuts().size()); } else if (target != createOp) { @@ -408,7 +492,7 @@ void createMemTileDMA( } // check if current createOp is of smaller size in link - if (target != createOp) numBlocks = target.size(); + if (target != createOp) numBlocks = objFifoSize(target); } createDMA(device, builder, createOp, target, channelDir, @@ -420,7 +504,8 @@ void createMemTileDMA( LogicalResult unrollForLoops(DeviceOp &device, const std::set &objectFifoTiles) { for (auto coreOp : device.getOps()) { - if (!objectFifoTiles.count(coreOp.getTileOp())) continue; + if (!objectFifoTiles.count(cast(coreOp.getTile().getDefiningOp()))) + continue; WalkResult res = coreOp.walk([&](scf::ForOp forLoop) { // look for operations on objectFifos @@ -432,8 +517,8 @@ LogicalResult unrollForLoops(DeviceOp &device, for (auto acqOp : body->getOps()) { if (acqOp.getOperation()->getParentOp() == forLoop) { found = true; - ObjectFifoCreateOp op = acqOp.getObjectFifo(); - objFifoSizes.insert(op.size()); + ObjectFifoCreateOp op = getObjectFifo(acqOp); + objFifoSizes.insert(objFifoSize(op)); } } // also counts original loop body @@ -481,8 +566,8 @@ void createUseLocks( builder.create(builder.getUnknownLoc(), lock, lockAction, numLocks); std::pair opPort = {op, static_cast(port)}; - acc[opPort] = - (acc[opPort] + numLocks) % op.size(); // update to next objFifo elem + acc[opPort] = (acc[opPort] + numLocks) % + objFifoSize(op); // update to next objFifo elem } /// Replace (not really - add) ObjectFifoReleaseOp with appropriate UseLockOp. @@ -493,10 +578,10 @@ void replaceReleaseOp( const DenseMap> &locksPerFifo, DenseMap, std::vector> &releaseOps) { - ObjectFifoCreateOp op = releaseOp.getObjectFifo(); + ObjectFifoCreateOp op = getObjectFifo(releaseOp); auto core = releaseOp->getParentOfType(); if (auto linkOp = getOptionalLinkOp(op)) - if (core.getTile() == *linkOp->getOptionalSharedTile()) + if (core.getTile() == *getOptionalSharedTile(*linkOp)) llvm::report_fatal_error( "currently cannot access objectFifo used in " "ObjectFifoLinkOp"); @@ -509,7 +594,7 @@ void replaceReleaseOp( { OpBuilder::InsertionGuard gg(builder); builder.setInsertionPointAfter(releaseOp); - createUseLocks(builder, op, port, relPerFifo, releaseOp.relNumber(), + createUseLocks(builder, op, port, relPerFifo, releaseOp.getSize(), LockAction::Release, objFifoLinks, locksPerFifo); } // register release op @@ -551,7 +636,7 @@ void splitFifo( auto consumerTileOp = cast(consumerTile.getDefiningOp()); if (isa(createOp.getElemNumber())) // +1 to account for 1st depth (producer) - consumerDepth = createOp.size(consumerIndex + 1); + consumerDepth = objFifoSize(createOp, consumerIndex + 1); else consumerDepth = findObjectFifoSize(device, consumerTileOp, createOp); @@ -560,9 +645,9 @@ void splitFifo( // rename and replace split objectFifo if (createOp.getConsumerTiles().size() > 1) consumerFifoName = - createOp.name().str() + "_" + std::to_string(consumerIndex) + "_cons"; + name(createOp).str() + "_" + std::to_string(consumerIndex) + "_cons"; else - consumerFifoName = createOp.name().str() + "_cons"; + consumerFifoName = name(createOp).str() + "_cons"; BDDimLayoutArrayAttr singletonFromStreamDims = BDDimLayoutArrayAttr::get(ctx, {consumerDims[consumerIndex]}); @@ -584,9 +669,9 @@ void splitFifo( consumerIndex++; auto linkOp = getOptionalLinkOp(createOp); if (!linkOp) continue; - for (ObjectFifoCreateOp fifoIn : linkOp->getInputObjectFifos()) - if (fifoIn.name() == createOp.name() && - consumerTile == *linkOp->getOptionalSharedTile() && + for (ObjectFifoCreateOp fifoIn : getInputObjectFifos(*linkOp)) + if (name(fifoIn) == name(createOp) && + consumerTile == *getOptionalSharedTile(*linkOp) && failed(SymbolTable::replaceAllSymbolUses( createOp, StringAttr::get(ctx, consumerFifoName), linkOp->getOperation()))) @@ -610,10 +695,10 @@ void replaceObjectAcquireOp( const DenseMap> &locksPerFifo, const DenseMap> &buffersPerFifo, DenseMap> &subviews) { - ObjectFifoCreateOp op = acquireOp.getObjectFifo(); + ObjectFifoCreateOp op = getObjectFifo(acquireOp); auto core = acquireOp->getParentOfType(); auto linkOp = getOptionalLinkOp(op); - if (linkOp && core.getTile() == *linkOp->getOptionalSharedTile()) + if (linkOp && core.getTile() == *getOptionalSharedTile(*linkOp)) llvm::report_fatal_error( "currently cannot access objectFifo used in " "ObjectFifoLinkOp"); @@ -632,7 +717,7 @@ void replaceObjectAcquireOp( // and the previous one int numRel = 0; for (auto relOp : releaseOps[opPort]) { - if (relOp.getObjectFifo() != op) continue; + if (getObjectFifo(relOp) != op) continue; Block *relBlock = relOp.getOperation()->getBlock(); Operation *relBlockDefOp = relBlock->getParentOp(); Block *relParentOpBlock = relBlockDefOp->getBlock(); @@ -649,22 +734,22 @@ void replaceObjectAcquireOp( // the ReleaseOps again later, // after the subview is created releaseOps[opPort].erase(releaseOps[opPort].begin()); - numRel += relOp.relNumber(); + numRel += relOp.getSize(); } } else if (acqBlock == relParentOpBlock) { if (!acquireOp->isBeforeInBlock(relBlockDefOp)) { releaseOps[opPort].erase(releaseOps[opPort].begin()); - numRel += relOp.relNumber(); + numRel += relOp.getSize(); } } else if (relBlock == acqParentOpBlock) { if (!acqBlockDefOp->isBeforeInBlock(relOp)) { releaseOps[opPort].erase(releaseOps[opPort].begin()); - numRel += relOp.relNumber(); + numRel += relOp.getSize(); } } else if (acqParentOpBlock == relParentOpBlock) { if (!acqBlockDefOp->isBeforeInBlock(relBlockDefOp)) { releaseOps[opPort].erase(releaseOps[opPort].begin()); - numRel += relOp.relNumber(); + numRel += relOp.getSize(); } } } @@ -685,7 +770,7 @@ void replaceObjectAcquireOp( } // acquire locks - size_t numLocks = acquireOp.acqNumber(); + size_t numLocks = acquireOp.getSize(); size_t alreadyAcq = acquiredIndices.size(); size_t numCreate = numLocks > alreadyAcq ? numLocks - alreadyAcq : 0; @@ -705,7 +790,7 @@ void replaceObjectAcquireOp( // create subview: buffers that were already acquired + new acquires for (int i = 0; i < numCreate; i++) { acquiredIndices.push_back(start); - start = (start + 1) % op.size(); + start = (start + 1) % objFifoSize(op); } std::vector subviewRefs; subviewRefs.reserve(acquiredIndices.size()); @@ -728,7 +813,9 @@ void createBuffersAndLocks( DenseMap> &locksPerFifo) { // add all tiles that contain an objectFifo to objectFifoTiles for later // loop unrolling pass - objectFifoTiles.insert(createOp.getProducerTileOp()); + TileOp producerTileOp = + cast(createOp.getProducerTile().getDefiningOp()); + objectFifoTiles.insert(producerTileOp); for (auto consumerTile : createOp.getConsumerTiles()) { auto consumerTileOp = cast(consumerTile.getDefiningOp()); objectFifoTiles.insert(consumerTileOp); @@ -739,14 +826,14 @@ void createBuffersAndLocks( if (requiresDMAs(createOp, shareDirection, splitBecauseLink)) { IntegerAttr elemNumberAttr; if (isa(createOp.getElemNumber())) - elemNumberAttr = builder.getI32IntegerAttr(createOp.size()); + elemNumberAttr = builder.getI32IntegerAttr(objFifoSize(createOp)); else elemNumberAttr = builder.getI32IntegerAttr( - findObjectFifoSize(device, createOp.getProducerTileOp(), createOp)); + findObjectFifoSize(device, producerTileOp, createOp)); createOp.setElemNumberAttr(elemNumberAttr); } - if (!createOp.size()) return; + if (!objFifoSize(createOp)) return; auto fifo = llvm::cast(createOp.getElemType()); auto elemType = llvm::cast(fifo.getElementType()); @@ -756,31 +843,31 @@ void createBuffersAndLocks( // the objFifo with elements of bigger size) auto linkOp = getOptionalLinkOp(createOp); if (linkOp) { - auto fifoIn = linkOp->getInputObjectFifos()[0], - fifoOut = linkOp->getOutputObjectFifos()[0]; + auto fifoIn = getInputObjectFifos(*linkOp)[0], + fifoOut = getOutputObjectFifos(*linkOp)[0]; // elements have already been created if (objFifoLinks.contains(*linkOp)) return; // if join, fifoOut has bigger size - if (linkOp->isJoin() && createOp.name() != fifoOut.name()) return; + if (isJoin(*linkOp) && name(createOp) != name(fifoOut)) return; // if distribute, fifoIn has bigger size - if (linkOp->isDistribute() && createOp.name() != fifoIn.name()) return; + if (isDistribute(*linkOp) && name(createOp) != name(fifoIn)) return; auto fifoInType = llvm::cast( - linkOp->getInputObjectFifos()[0].getElemType()), + getInputObjectFifos(*linkOp)[0].getElemType()), fifoOutType = llvm::cast( - linkOp->getOutputObjectFifos()[0].getElemType()); + getOutputObjectFifos(*linkOp)[0].getElemType()); auto elemInType = llvm::cast(fifoInType.getElementType()), elemOutType = llvm::cast(fifoOutType.getElementType()); int64_t inSize = elemInType.getNumElements(); if (int64_t outSize = elemOutType.getNumElements(); inSize >= outSize) { - if (createOp.name() != fifoIn.name()) return; - } else if (linkOp->getOutputObjectFifos()[0] != createOp) + if (name(createOp) != name(fifoIn)) return; + } else if (getOutputObjectFifos(*linkOp)[0] != createOp) return; } TileOp creationTile; if (shareDirection == NONE || shareDirection == LHS) - creationTile = createOp.getProducerTileOp(); + creationTile = producerTileOp; else creationTile = cast(createOp.getConsumerTiles()[0].getDefiningOp()); @@ -792,7 +879,7 @@ void createBuffersAndLocks( OpBuilder::InsertionGuard gg(builder); builder.setInsertionPointAfter(*std::prev(tiles.end(), 1)); - size_t numElem = createOp.size(); + size_t numElem = objFifoSize(createOp); // if shimTile external buffers are collected from input code AMDAIEDeviceModel deviceModel = getDeviceModel(static_cast(device.getDevice())); @@ -802,7 +889,7 @@ void createBuffersAndLocks( for (int ofElemIndex = 0; ofElemIndex < numElem; ofElemIndex++) { auto buff = builder.create( builder.getUnknownLoc(), elemType, creationTile, - builder.getStringAttr(createOp.name().str() + "_buff_" + + builder.getStringAttr(name(createOp).str() + "_buff_" + std::to_string(ofElemIndex)), /*address*/ nullptr, /*initial_value*/ nullptr, /*mem_bank*/ nullptr); @@ -812,9 +899,9 @@ void createBuffersAndLocks( } if (linkOp) { - if (linkOp->isDistribute()) + if (isDistribute(*linkOp)) numElem *= linkOp->getFifoOuts().size(); - else if (linkOp->isJoin()) + else if (isJoin(*linkOp)) numElem *= linkOp->getFifoIns().size(); objFifoLinks[*linkOp] = createOp; } @@ -832,7 +919,7 @@ void createBuffersAndLocks( prodLockID, numElem); prodLock.getOperation()->setAttr( SymbolTable::getSymbolAttrName(), - builder.getStringAttr(createOp.name().str() + "_prod_lock")); + builder.getStringAttr(name(createOp).str() + "_prod_lock")); std::vector locks{prodLock}; int consLockID = lockAnalysis.getLockID(creationTile); @@ -844,7 +931,7 @@ void createBuffersAndLocks( consLockID, 0); consLock.getOperation()->setAttr( SymbolTable::getSymbolAttrName(), - builder.getStringAttr(createOp.name().str() + "_cons_lock")); + builder.getStringAttr(name(createOp).str() + "_cons_lock")); locks.push_back(consLock); locksPerFifo[createOp] = locks; @@ -865,7 +952,7 @@ void createFlowsAndTileDMAs( &objFifoLinks, &buffersPerFifo]( ObjectFifoCreateOp op, DMAChannelDir channelDir, int channelIndex, BDDimLayoutArrayAttr dims) { - auto producerOp = op.getProducerTileOp(); + TileOp producerOp = cast(op.getProducerTile().getDefiningOp()); if (deviceModel.isShimTile(producerOp.getCol(), producerOp.getRow())) return; else if (deviceModel.isMemTile(producerOp.getCol(), producerOp.getRow())) @@ -876,6 +963,9 @@ void createFlowsAndTileDMAs( objFifoLinks, buffersPerFifo, locksPerFifo); }; // create producer tile DMA + + TileOp producerProducerTileOp = + cast(producer.getProducerTile().getDefiningOp()); SwitchDMAConnection producerChan = dmaAnalysis.getProducerDMAChannel(producer.getProducerTile()); createDMA(producer, static_cast(producerChan.direction), @@ -883,12 +973,12 @@ void createFlowsAndTileDMAs( // generate objectFifo allocation info OpBuilder::InsertionGuard g(builder); builder.setInsertionPoint(&device.getBody()->back()); - if (deviceModel.isShimTile(producer.getProducerTileOp().getCol(), - producer.getProducerTileOp().getRow())) + if (deviceModel.isShimTile(producerProducerTileOp.getCol(), + producerProducerTileOp.getRow())) builder.create( builder.getUnknownLoc(), producer.getName(), static_cast(producerChan.direction), - producerChan.channel, producer.getProducerTileOp().getCol()); + producerChan.channel, producerProducerTileOp.getCol()); for (auto consumer : consumers) { // create consumer tile DMA @@ -901,12 +991,15 @@ void createFlowsAndTileDMAs( // generate objectFifo allocation info OpBuilder::InsertionGuard gg(builder); builder.setInsertionPoint(&device.getBody()->back()); - if (deviceModel.isShimTile(consumer.getProducerTileOp().getCol(), - consumer.getProducerTileOp().getRow())) + + TileOp consumerProducerTileOp = + cast(consumer.getProducerTile().getDefiningOp()); + if (deviceModel.isShimTile(consumerProducerTileOp.getCol(), + consumerProducerTileOp.getRow())) builder.create( builder.getUnknownLoc(), producer.getName(), static_cast(consumerChan.direction), - consumerChan.channel, consumer.getProducerTileOp().getCol()); + consumerChan.channel, consumerProducerTileOp.getCol()); // create flow { @@ -1029,8 +1122,7 @@ struct AMDAIEObjectFifoStatefulTransformPass : mlir::OperationPass { // Replace subview.access ops coreOp.walk([&](ObjectFifoSubviewAccessOp accessOp) { auto acqOp = accessOp.getSubview().getDefiningOp(); - if (ObjectFifoCreateOp op = acqOp.getObjectFifo(); - getOptionalLinkOp(op)) + if (ObjectFifoCreateOp op = getObjectFifo(acqOp); getOptionalLinkOp(op)) llvm::report_fatal_error( "currently cannot access objectFifo used in " "ObjectFifoLinkOp"); diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/PluginRegistration.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/PluginRegistration.cpp index 134f3e30f..2ef29d294 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/PluginRegistration.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/PluginRegistration.cpp @@ -4,8 +4,8 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "aie/Dialect/AIE/IR/AIEDialect.h" -#include "aie/Dialect/AIEX/IR/AIEXDialect.h" +#include "aie/AIEDialect.h" +#include "aie/AIEXDialect.h" #include "aie/Passes.h" #include "aievec/AIEVecDialect.h" #include "aievec/Passes.h" diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETargetDirect.h b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETargetDirect.h deleted file mode 100644 index ebbd07668..000000000 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETargetDirect.h +++ /dev/null @@ -1,24 +0,0 @@ -// Copyright 2024 The IREE Authors -// -// 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 - -#ifndef IREE_AMD_AIE_TARGET_DIRECT_AIETARGET_H_ -#define IREE_AMD_AIE_TARGET_DIRECT_AIETARGET_H_ - -#include - -#include "iree-amd-aie/Target/AIETarget.h" -#include "iree/compiler/Dialect/HAL/Target/TargetBackend.h" -#include "iree/compiler/Dialect/HAL/Target/TargetDevice.h" -#include "iree/compiler/Utils/OptionUtils.h" - -namespace mlir::iree_compiler::AMDAIE { - -std::shared_ptr createBackendDirect( - const AMDAIEOptions &options); - -} // namespace mlir::iree_compiler::AMDAIE - -#endif // IREE_AMD_AIE_TARGET_DIRECT_AIETARGET_H_ From 17f2067b63895804c31b24fa49c33954efcf421a Mon Sep 17 00:00:00 2001 From: max Date: Sun, 4 Aug 2024 10:02:13 -0500 Subject: [PATCH 03/12] remove interfaces --- .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 40 +- .../plugins/target/AMD-AIE/aie/AIEDialect.h | 30 +- .../target/AMD-AIE/aie/AIEInterfaces.td | 102 +-- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 834 +----------------- .../aie/AMDAIEAssignBufferDescriptorIDs.cpp | 4 +- .../plugins/target/AMD-AIE/aie/CMakeLists.txt | 2 +- 6 files changed, 61 insertions(+), 951 deletions(-) diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index fab094687..4cdba7b7c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -154,7 +154,7 @@ static TileElement getParentTileElement(Operation *op) { struct UsesAreAccessable { static LogicalResult verifyTrait(Operation *op) { auto thisElement = cast(op); - auto thisID = thisElement.getTileID(); + auto thisID = thisElement.getTileLoc(); auto users = op->getResult(0).getUsers(); const auto &targetModel = getTargetModel(op); for (auto *user : users) { @@ -163,13 +163,13 @@ struct UsesAreAccessable { if (llvm::isa_and_nonnull(user->getParentOp())) return success(); if (auto element = getParentTileElement(user)) { - auto tileID = element.getTileID(); - if (!targetModel.isLegalMemAffinity(tileID.col, tileID.row, thisID.col, + auto TileLoc = element.getTileLoc(); + if (!targetModel.isLegalMemAffinity(TileLoc.col, TileLoc.row, thisID.col, thisID.row)) return (op->emitOpError("in Column ") << thisID.col << " and Row " << thisID.row << " is accessed from an unreachable tile in Column " - << tileID.col << " and Row " << tileID.row) + << TileLoc.col << " and Row " << TileLoc.row) .attachNote(user->getLoc()) << "user"; } else { @@ -412,7 +412,7 @@ LogicalResult HasValidBDs::verifyTrait(Operation *op) { auto element = cast(op); const auto &targetModel = getTargetModel(op); int bdMax = - targetModel.getNumBDs(element.getTileID().col, element.getTileID().row); + targetModel.getNumBDs(element.getTileLoc().col, element.getTileLoc().row); int bdNum = 0; for (auto &block : element.getBody()) { @@ -545,18 +545,18 @@ ParseResult parseObjectFifoConsumerTiles( void printObjectFifoConsumerTiles(OpAsmPrinter &printer, Operation *op, OperandRange tiles, BDDimLayoutArrayArrayAttr dimsPerTileAttr) { - size_t tileIdx = 0; + size_t TileLocx = 0; for (auto tile : tiles) { printer << tile; - if (dimsPerTileAttr && tileIdx < dimsPerTileAttr.size() && - dimsPerTileAttr[tileIdx] && !dimsPerTileAttr[tileIdx].empty()) { + if (dimsPerTileAttr && TileLocx < dimsPerTileAttr.size() && + dimsPerTileAttr[TileLocx] && !dimsPerTileAttr[TileLocx].empty()) { printer << " fromStream "; - printer.printStrippedAttrOrType(dimsPerTileAttr[tileIdx]); + printer.printStrippedAttrOrType(dimsPerTileAttr[TileLocx]); } - if (tileIdx < tiles.size() - 1) { + if (TileLocx < tiles.size() - 1) { printer << ", "; } - tileIdx++; + TileLocx++; } } @@ -1290,7 +1290,7 @@ int32_t xilinx::AIE::getBufferBaseAddress(Operation *bufOp) { } void xilinx::AIE::collectTiles(DeviceOp &device, - DenseMap &tiles) { + DenseMap &tiles) { for (auto tile : device.getOps()) { int colIndex = tile.colIndex(); int rowIndex = tile.rowIndex(); @@ -1537,17 +1537,17 @@ LogicalResult DMABDOp::verify() { "transfer length must be multiple of 4 (i.e., represent " "4 byte aligned address)"); - TileID parentTileId = getParentTileElement(getOperation()).getTileID(); + TileLoc parentTileLoc = getParentTileElement(getOperation()).getTileLoc(); if (getOperation()->getParentOfType() && - (getBufferOp().getTileOp().colIndex() != parentTileId.col || - getBufferOp().getTileOp().rowIndex() != parentTileId.row)) + (getBufferOp().getTileOp().colIndex() != parentTileLoc.col || + getBufferOp().getTileOp().rowIndex() != parentTileLoc.row)) return emitOpError( "Core tile DMAs can only access a buffer in the same tile."); const AIETargetModel &targetModel = getTargetModel(getOperation()); - uint32_t maxBds = targetModel.getNumBDs(parentTileId.col, parentTileId.row); + uint32_t maxBds = targetModel.getNumBDs(parentTileLoc.col, parentTileLoc.row); if (std::optional bdId = getBdId(); bdId.has_value() && static_cast(*bdId) >= maxBds) return emitOpError("bdId attribute exceeds max: ") << maxBds - 1; @@ -1604,7 +1604,7 @@ LogicalResult DMABDOp::verify() { if (dims->size() != paddims->size()) return emitOpError() << "Mismatch number of dimensions between padding(s)" << " and wrap(s) and stride(s)."; - if (!targetModel.isMemTile(parentTileId.col, parentTileId.row)) + if (!targetModel.isMemTile(parentTileLoc.col, parentTileLoc.row)) return emitOpError() << "Padding is only supported by memtile dma bds."; int actuallen = 1; for (unsigned i = 0; i < paddims->size(); i++) { @@ -1626,8 +1626,8 @@ LogicalResult DMABDOp::verify() { return emitOpError() << "Inner-most padding-after count must result in" << " padding in 32-bit words."; } - if (targetModel.isMemTile(parentTileId.col, parentTileId.row) || - targetModel.isCoreTile(parentTileId.col, parentTileId.row)) { + if (targetModel.isMemTile(parentTileLoc.col, parentTileLoc.row) || + targetModel.isCoreTile(parentTileLoc.col, parentTileLoc.row)) { if (auto baseAddr = getBufferOp().getAddress(); baseAddr.has_value()) { int offsetInBytes = *baseAddr + getOffsetInBytes(); if (offsetInBytes % 4) @@ -1693,7 +1693,7 @@ LogicalResult SwitchboxOp::verify() { return connectOp.emitOpError() << "; connecting " << to_string(source) << " to " << to_string(dest) << " on " - << to_string(this->getTileOp().getTileID()) + << to_string(this->getTileOp().getTileLoc()) << " targets same dst as another connect op; existing " "destinations: " << llvm::join(llvm::map_range( diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index f15f8b3fe..a8254f17b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -12,6 +12,7 @@ #define MLIR_AIE_DIALECT_H #include "AIEEnums.h" +#include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" #include "mlir/Dialect/Func/IR/FuncOps.h" @@ -25,22 +26,6 @@ #include "mlir/IR/Types.h" namespace xilinx::AIE { - -// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) -// has valid BDs. -template -struct HasValidBDs : mlir::OpTrait::TraitBase { - static mlir::LogicalResult verifyTrait(mlir::Operation *op); -}; - -// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) -// has valid channels. -template -struct HasValidDMAChannels - : mlir::OpTrait::TraitBase { - static mlir::LogicalResult verifyTrait(mlir::Operation *op); -}; - template bool hasName(T &op) { return bool(op.getOperation()->template getAttrOfType( @@ -56,6 +41,13 @@ mlir::StringAttr name(T &op) { << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; llvm::report_fatal_error("couldn't get name"); } + +class TileOp; +template +inline TileOp getTileOp(T op) { + return cast(op.getTile().getDefiningOp()); +} + } // namespace xilinx::AIE namespace xilinx::AIE { @@ -244,9 +236,6 @@ typedef struct DMAChannel { } } DMAChannel; -const AIETargetModel &getTargetModel(mlir::Operation *op); -const AIETargetModel &getTargetModel(AIEDevice device); - mlir::ParseResult parseObjectFifoProducerTile( mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, BDDimLayoutArrayAttr &dimensions); @@ -275,7 +264,8 @@ int32_t getBufferBaseAddress(mlir::Operation *bufOp); namespace xilinx::AIE { void collectTiles(DeviceOp &device, - llvm::DenseMap &tiles); + llvm::DenseMap &tiles); void collectBuffers( DeviceOp &device, diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td index 5bf2dcdd1..9aaca09a1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td @@ -18,75 +18,6 @@ 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"> { - string cppNamespace = "::xilinx::AIE"; -} - -// Op is a DMA-like operation with valid channels -def HasValidDMAChannels : NativeOpTrait<"HasValidDMAChannels"> { - string cppNamespace = "::xilinx::AIE"; -} - -def PredIsCoreTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isCoreTile(llvm::cast($_op).getTileID().col," - "llvm::cast($_op).getTileID().row)">; -def PredIsMemTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isMemTile(llvm::cast($_op).getTileID().col," - "llvm::cast($_op).getTileID().row)">; -def PredIsShimNOCTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isShimNOCTile(llvm::cast($_op).getTileID().col," - "llvm::cast($_op).getTileID().row)">; -def PredIsShimPLTile : CPred<"xilinx::AIE::getTargetModel(&$_op).isShimPLTile(llvm::cast($_op).getTileID().col," - "llvm::cast($_op).getTileID().row)">; - -def IsCoreTile : PredOpTrait<"op exists in a core tile", PredIsCoreTile>; -def IsMemTile : PredOpTrait<"op exists in a MemTile", PredIsMemTile>; -def IsTileWithMemory : PredOpTrait<"op exists in a tile with local memory", Or<[PredIsCoreTile, PredIsMemTile]>>; -def IsShimTile : PredOpTrait<"op exists in a shim tile", Or<[PredIsShimNOCTile, PredIsShimPLTile]>>; -def IsShimNOCTile : PredOpTrait<"op exists in a shim tile with NOC connection", PredIsShimNOCTile>; -def IsShimPLTile : PredOpTrait<"op exists in a shim tile with PL interface", PredIsShimPLTile>; - -def FlowEndPoint : OpInterface<"FlowEndPoint"> { - let description = [{ - Interface for operations that have interconnect-like properties, - enabling them to host flows for routing. - }]; - let cppNamespace = "::xilinx::AIE"; - let methods = [ - InterfaceMethod<[{}], - "int", "colIndex", (ins ) - >, - InterfaceMethod<[{}], - "int", "rowIndex", (ins ) - > - ]; -} - -def Interconnect : OpInterface<"Interconnect"> { - let description = [{ - Interface for operations that have interconnect-like properties, - enabling them to host flows for routing. - }]; - let cppNamespace = "::xilinx::AIE"; - - let methods = [ - InterfaceMethod<[{}], - "mlir::Region &", "getConnections", (ins ) - >, - InterfaceMethod<[{}], - "int", "colIndex", (ins ) - >, - InterfaceMethod<[{}], - "int", "rowIndex", (ins ) - >, - InterfaceMethod<[{}], - "size_t", "getNumSourceConnections", (ins "WireBundle":$bundle) - >, - InterfaceMethod<[{}], - "size_t", "getNumDestConnections", (ins "WireBundle":$bundle) - > - ]; -} - - def TileElement : OpInterface<"TileElement", [ DeclareOpInterfaceMethods, ]> { @@ -95,17 +26,28 @@ def TileElement : OpInterface<"TileElement", [ }]; let cppNamespace = "::xilinx::AIE"; let methods = [ + InterfaceMethod<[{ + Return the Tile where the element is located. + }], + "TileOp", "getTileOp", (ins ), + /*methodBody=*/[{}], + /*defaultImpl=*/[{ + ConcreteOp op = llvm::cast(this->getOperation()); + return cast(op.getTile().getDefiningOp()); + }] + >, InterfaceMethod<[{ Return the location of the Tile where the element is located. }], - "xilinx::AIE::TileID", "getTileID", (ins ), + "mlir::iree_compiler::AMDAIE::TileLoc", "getTileLoc", (ins ), /*methodBody=*/[{}], /*defaultImpl=*/[{ ConcreteOp op = llvm::cast(this->getOperation()); - return op.getTileOp().getTileID(); + return op.getTileOp().getTileLoc(); }] >, ]; + let extraTraitClassDeclaration = [{ void getAsmResultNames( llvm::function_ref setNameFn) { @@ -113,26 +55,12 @@ def TileElement : OpInterface<"TileElement", [ std::string nameWithoutDialect = op.getOperationName().str().substr(op.getOperationName().find('.') + 1); setNameFn(op.getResult(), nameWithoutDialect + "_" + - std::to_string(getTileID().col) + "_" + - std::to_string(getTileID().row)); + std::to_string(getTileLoc().col) + "_" + + std::to_string(getTileLoc().row)); } }]; } -def AIETarget : OpInterface<"AIETarget"> { - let description = [{ - Interface for operations that model an array of AIEngine cores. - }]; - let cppNamespace = "::xilinx::AIE"; - let methods = [ - InterfaceMethod<[{ - Return the target model describing the characteristics of how this operation will be implemented. - }], - "const ::xilinx::AIE::AIETargetModel&", "getTargetModel", (ins ) - > - ]; -} - // Don't delete - see AIEDialect::myVerifyOffsetSizeAndStrideOp def MyOffsetSizeAndStrideOpInterface: OpInterfaceTrait<"::xilinx::AIE::MyOffsetSizeAndStrideOpInterface"> {} diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index 977f9a1cf..b268e74e9 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -27,34 +27,10 @@ class AIE_Op traits = []> : def AIE_DeviceOp: AIE_Op<"device", [ - AIETarget, HasParent<"mlir::ModuleOp">, + HasParent<"mlir::ModuleOp">, SymbolTable, SingleBlock, NoTerminator, IsolatedFromAbove ]> { let summary = "Define an AIE design targetting a complete device"; - let description = [{ - This operation describes a design that executes on a particular AIEngine device. - It exists at the toplevel of a design; although currently it does not replace the - default toplevel module in MLIR, the intention is that this could be the case - in the future. - - When using this operation, all resources in a physical device are available and - the design does not need to be concerned with other potential users of a physical - device. In addition, within an `aie.device` operation, tile addresses are absolute - coordinates and are not intended to describe a relocatable design. To describe - a portion of a device which may be relocatable, the intention would be to provide another - operation, for instance maybe `aie.segment`. - The design itself is described using a region of code contained by the device - operation. - - Example: - ``` - aie.device(xcvc1902) { - %tile = aie.tile(1, 1) - %CORE = aie.core(%tile) { ... } - } - ``` - }]; - let arguments = (ins AIEDevice:$device); let regions = (region AnyRegion:$body_region); let assemblyFormat = [{ @@ -65,7 +41,6 @@ def AIE_DeviceOp: AIE_Op<"device", [ def AIE_TileOp: AIE_Op<"tile", [ Pure, - FlowEndPoint, DeclareOpInterfaceMethods, DeclareOpInterfaceMethods ]>, Results<(outs Index:$result)> { @@ -75,18 +50,6 @@ def AIE_TileOp: AIE_Op<"tile", [ ); let summary = "Declare an AIE tile"; - let description = [{ - This operation creates an AIE tile in the AIE array. We specify what the column and the row of the tile. - - A tile encompasses core module (CoreOp), memory module (MemOp), stream switch (SwitchboxOp), - memory buffer (BufferOp), and lock (LockOp). - - A tile is a logical abstraction. We use a tile to establish an ownership of a hardware entity - to it. - Note that row 0 of the Tile array is different from other rows, since it models the shim interface between - the AIE array proper and the PL. The South-West/Lower Right most core exists in Tile(0,1) - }]; - let assemblyFormat = [{ `(` $col `,` $row `)` attr-dict }]; @@ -107,33 +70,17 @@ def AIE_TileOp: AIE_Op<"tile", [ def AIE_EndOp: AIE_Op<"end", [Terminator]> { let summary = "end op"; - let description = [{ - A generic terminator operation for AIE ops' regions. - }]; let assemblyFormat = [{ attr-dict }]; } def AIE_SwitchboxOp: AIE_Op<"switchbox", [ - Interconnect, TileElement, + TileElement, SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index:$result)> { let arguments = (ins Index:$tile); let summary = "Declare a switch"; - let description = [{ - This operation represents the switchbox that is part of a tile. A switchbox is configured - by code in its region, representing various connections - - Example: - ``` - %tile = aie.tile(1, 1) - aie.switchbox(%tile) { - aie.connect<"West" : 0, "Core" : 1> - } - ``` - }]; - let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; @@ -149,27 +96,13 @@ def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ ]>, Results<(outs Index)> { let arguments = (ins I32Attr:$col); let summary = "Declare a switch in the PL shim"; - let description = [{ - - A switch in the Shim. - AXI-Stream Master Ports AXI-Stream Slave Ports - 6 Ports to North (Core Tile) 4 Ports from North (Core Tile) - 4 Ports to West 4 Ports from West - 4 Ports to East 4 Ports from East - 6 Ports to South(DMA, NoC I/F, PL I/F) 8 Ports from South (DMA, NoC I/F, PL I/F) - 2 Ports to FIFOs 2 Ports from FIFOs - 1 Port for control packet for Shim register access - 1 Port for response to access for Shim registers - 1 Port for trace packet from Shim - - }]; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $col `)` regions attr-dict }]; let hasVerifier = 1; } def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ - Interconnect, TileElement, IsShimTile, + TileElement, SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { @@ -177,19 +110,6 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ ins Index:$tile ); let summary = "Declare a switch in the PL shim"; - let description = [{ - This operation represents the additional interconnect that is part of a shim interface tile. - Like the `aie.switchbox` operation, `aie.shim_mux` is configured - by code in its region, but can only contain connect operations - - Example: - ``` - %tile = aie.tile(1, 1) - aie.shim_mux(%tile) { - aie.connect<"North" : 0, "DMA" : 1> - } - ``` - }]; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; @@ -201,35 +121,13 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ // def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ // FlowEndPoint, TileElement, HasValidBDs, -// HasValidDMAChannels, IsShimNOCTile, +// HasValidDMAChannels // DeclareOpInterfaceMethods // ]>, Results<(outs Index)> { // let arguments = ( // ins Index:$tile // ); // let summary = "Declare a DMA in the PL shim"; -// let description = [{ -// This operation creates a DMA that belongs to a shim tile. -// The region of a ShimDMAOp is used to setup the DMAs and Block Descriptors. -// -// Example: -// ``` -// %buf = aie.external_buffer : memref<256xi64> -// %lock1 = aie.lock(%t70, 1) -// -// %dma = aie.shim_dma(%t70) { -// aie.dma_start(MM2S, 0, ^bd0, ^end) -// ^bd0: -// aie.use_lock(%lock1, Acquire, 1) -// aie.dma_bd(%buf : memref<512 x i16>, 0, 512) -// aie.use_lock(%lock1, Release, 0) -// aie.next_bd ^bd0 -// ^end: -// aie.end -// } -// ``` -// Create the shim_dma for tile `%t70` and setup one DMA channel and one Buffer Descriptor. -// }]; // let regions = (region AnyRegion:$body); // let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; // let hasVerifier = 1; @@ -243,7 +141,7 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ // } def AIE_CoreOp: AIE_Op<"core", [ - FlowEndPoint, IsCoreTile, TileElement, + TileElement, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let arguments = ( @@ -253,36 +151,6 @@ def AIE_CoreOp: AIE_Op<"core", [ OptionalAttr:$elf_file ); let summary = "Declare a core module"; - let description = [{ - This operation represents an AIEngine processor core belonging to a tile. - The region of a CoreOp contains code that gets run on the AIE core. This code will - typically be outlined into the LLVM dialect, eventually resulting in a binary file - for each core. The name of this file can be be specified using the `elf_file` - attribute. - - This op has an optional `stackSize` attribute, to control the amount of memory (in bytes) - reserved for the stack. The default value is 1024. The stack (and other data allocations) - are always stored in the local core memory, to avoid conflicts with static data allocations - in other cores. - - Examples: - ``` - %tile = aie.tile(1, 1) - %lock11_8 = aie.lock(%tile, 8) - aie.core(%tile) { - aie.use_lock(%lock11_8, "Acquire", 1) - aie.use_lock(%lock11_8, "Release", 0) - aie.end - } - ``` - ``` - %tile = aie.tile(3, 3) - aie.core(%tile) { - aie.end - } { stackSize = 2048 : i32, elf_file = "core_33.elf" } - ``` - }]; - let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; @@ -306,23 +174,6 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ConfinedAttr]>:$dest_channel ); let summary = "A circuit-switched connection inside a switchbox"; - let description = [{ - This operation represents a programmed circuit-switched connection in a stream switch. - It associates a source bundle and source channel with a destination bundle and a destination channel. - This operation must exist within an `aie.switchbox` or `aie.shim_switchbox` operation. - All of the `aie.connect` operations in a switchbox must have a different destinations. - All of the `aie.connect` operations must also have a destination which is different from all - of the `aie.masterset` operations in the same switchbox. - - Example: - ``` - %tile = aie.tile(1, 1) - aie.switchbox(%tile) { - aie.connect<"West" : 0, "Core" : 1> - } - ``` - }]; - let assemblyFormat = [{ `<` $source_bundle `:` $source_channel `,` $dest_bundle `:` $dest_channel `>` attr-dict }]; @@ -338,21 +189,6 @@ def AIE_FlowOp: AIE_Op<"flow", []> { ConfinedAttr]>:$dest_channel ); let summary = "A logical circuit-switched connection between cores"; - let description = [{ - The `aie.flow` operation represents a circuit switched connection between two endpoints, usually - `aie.tile` operations. During routing, this is replaced by `aie.connect` operations which represent - the programmed connections inside a switchbox, along with `aie.wire` operations which represent - physical connections between switchboxes and other components. - - Example: - ``` - %00 = aie.tile(0, 0) - %11 = aie.tile(1, 1) - %01 = aie.tile(0, 1) - aie.flow(%00, "DMA" : 0, %11, "Core" : 1) - ``` - }]; - let assemblyFormat = [{ `(` $source `,` $source_bundle `:` $source_channel `,` $dest `,` $dest_bundle `:` $dest_channel `)` attr-dict }]; @@ -367,26 +203,6 @@ def AIE_AMSelOp: AIE_Op<"amsel", [ ConfinedAttr, IntMaxValue<3>]>:$msel ); let summary = "Declare an arbiter of a switchbox with a master select value (arbiter + msel)"; - let description = [{ - A combination of arbiter ID and master select (msel) value. - This op is used as a pointer to select the arbiter for routing a packet-switched flow - - Example: - ``` - %a0_0 = aie.amsel<5>(3) - %m1 = aie.masterset("East" : 0, %a0_0 ) - aie.packet_rules("South" : 0) { - aie.rule(0x1F, 0x10, %a0_0) - } - ``` - This code associates arbiter 5 with msel=3. A packet-switched connection is made routing - traffic from the South:0 port to the East:0 port using this arbiter. - There are 6 arbiters per switchbox and 4 possible master select values. - See also [MasterSetOp](#aiemasterset-aiemastersetop), - [PacketRulesOp](#aiepacketrules-aiepacketrulesop), and - [PacketRuleOp](#aierule-aiepacketruleop) for more information. - }]; - let assemblyFormat = [{ `<` $arbiterID `>` `(` $msel `)` attr-dict }]; @@ -411,33 +227,6 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ Variadic:$amsels ); let summary = "Packet switched input connection"; - let description = [{ - A Packet switched connection inside a switchbox. - This operation specifies the configuration for a master port. - - Example: - ``` - %a0_m2 = aie.amsel<0>(2) - aie.masterset("Core" : 0, %a0_m2) - ``` - - The code will configure the master port <"Core" : 0> to use arbiter 0 with msel 2 - (see AMSelOp for more details regarding AMSel) - - In the current architecture, a master port can only be associated with one arbiter. However, - a master port can be activated by different msels from one arbiter - - Example: - ``` - %a1_0 = aie.amsel<1>(0) - %a1_1 = aie.amsel<1>(1) - %a2_3 = aie.amsel<2>(3) - - aie.masterset("West" : 2, %a1_0, %a2_3) // this is illegal, please don't do this - aie.masterset("West" : 3, %a1_0, %a1_1) // this is OK - ``` - }]; - let assemblyFormat = [{ `(` $dest_bundle `:` $dest_channel `,` $amsels `)` attr-dict }]; @@ -450,15 +239,6 @@ def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"En ); let regions = (region AnyRegion:$rules); let summary = "Packet switched routing rules"; - let description = [{ - This operation defines packet-switched routing configuration for packets entering a switchbox. - It references a port of the containing swithcbox, which be unique among other packetRules - operations and [aie.connect]($aieconnect-aieconnectop) operations in the containing switchbox. - It contains a region of up to 4 [aie.rule](#aierule-aiepacketruleop) operations. - - See [aie.rule](#aierule-aiepacketruleop) for an example. - }]; - let assemblyFormat = [{ `(` $source_bundle `:` $source_channel `)` regions attr-dict }]; let hasVerifier = 1; } @@ -470,37 +250,6 @@ def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { Index:$amsel ); let summary = "Packet switched routing rule"; - let description = [{ - This operation defines a matching rule and a destination for packet-switched - connections in a switchbox. Routing is based on the ID field of packet arriving on the - matching port of the containing [aie.packetRules](#aiepacketrules-aiepacketrulesop). - The ID is first bitwise-AND'd with the mask and then checked for equality with the given ID. - It is routed to arbiter and master set associated with the first matching entry. - - Example: - LUT ID | Mask | ID | Arbiter | Msel - --- | --- | --- | --- | --- - 0 | 5'b11111 | 5'b00010 | 4 | 1 - 1 | 5'b11011 | 5'b00001 | 3 | 2 - 2 | | | | - 3 | | | | - - If a packet flow that has an ID of 2, it will be directed to the arbiter 4 with msel 1, - If a packet flow that has an ID of 1 or 5, it will be directed to the arbiter 3 with msel 2, - - We encapsulate the configuration table as follows: - Example: - ``` - %a4_1 = aie.amsel<4>(1) - %a3_2 = aie.amsel<3>(2) - - aie.packet_rules("Core" : 0) { - aie.rule(0x1F, 0x2, %a4_1) - aie.rule(0x1B, 0x1, %a3_2) - } - ``` - }]; - let assemblyFormat = [{ `(` $mask `,` $value `,` $amsel `)` attr-dict }]; @@ -509,21 +258,6 @@ def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndOp">]> { let summary = "Packet switched flow"; - let description = [{ - A logical packet-switched flow between tiles. During place and - route, this is replaced by MasterSets and PacketRules inside - switchboxes. - - Example: - ``` - %01 = aie.tile(0, 1) - aie.packet_flow(0x10) { - aie.packet_source<%01, "Core" : 0> - aie.packet_dest<%01, "Core" : 0> - } - ``` - }]; - let arguments = ( ins I8Attr:$ID, OptionalAttr:$keep_pkt_header @@ -541,13 +275,6 @@ def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { ConfinedAttr]>:$channel ); let summary = "A sourceport"; - let description = [{ - A object representing the destination of a packet-switched flow. This must exist - within an [aie.packet_flow](#aiepacketflow-aiepacketflowop) operation. - - See [aie.packet_flow](#aiepacketflow-aiepacketflowop) for an example. - }]; - let assemblyFormat = [{ `<` $tile `,` $bundle `:` $channel `>` attr-dict }]; @@ -560,14 +287,6 @@ def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { ConfinedAttr]>:$channel ); let summary = "A destination port"; - let description = [{ - A object representing the destination of a packet-switched flow. This must exist - within an [aie.packet_flow](#aiepacketflow-aiepacketflowop) operation. The destination - Must be unique within a design. - - See [aie.packet_flow](#aiepacketflow-aiepacketflowop) for an example. - }]; - let assemblyFormat = [{ `<` $tile `,` $bundle `:` $channel `>` attr-dict }]; @@ -575,25 +294,6 @@ def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { let summary = "Enable packet headers for a dma block descriptor"; - 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.dma_bd. - The block descriptor specifies what lock to use and the buffer configuration. - - Example: - ``` - // this defines a BD that uses lock %lck0 and buffer %buf0 - ^bd5: - aie.use_lock(%lck, "Acquire", 0) - aie.dma_bd_packet(0x4, 0xD) - aie.dma_bd(<$buf0 : memref<512xi32>, 0, 512>, 1) - aie.use_lock(%lck, "Release", 1) - br ^bd6 // point to the next Block, which is also a different Block Descriptor - ``` - }]; - let arguments = ( ins I32Attr:$packet_type, I32Attr:$packet_id @@ -608,114 +308,6 @@ def AIE_DMABDOp: AIE_Op<"dma_bd", [ ParentOneOf<["MemOp", "MemTileDMAOp"]>, ]> { let summary = "Declare a dma buffer descriptor op"; - let description = [{ - This operation describes a buffer descriptor for DMA operations. In particular, it specifies - what buffer to use, and optionally: - - 1. the offset into the buffer; - 2. the transfer length; - 3. the sizes and strides for n-d tensor addressing (described below); - 4. the "bd_id" with which to associate the buffer descriptor (most often left empty). - 5. the number of zeros to pad before and after every dimension of an n-d tensor (described below); - - `offset`, `len`, `size`s and `stride`s are all denominated in element width; e.g., transferring the whole of - `memref<512xi32>` means `len == 512`, and also while transferring the whole of `memref<512xi16>`, `len == 512`. - - The only caveat to this "everything-is-in-terms-of-element-width" rule is regarding the inner-most dimension's stride - (see [Important gotcha regarding strides](#important-gotcha-regarding-strides) below). - - `dma_bd` ops must appear in their own BBs (basic blocks) and such BBs can (optionally) include `use_lock` - operations (specifying an "acquire" and a "release" lock; see the `use_lock` operation) and subsequent BDs in - a "chain" of BDs (using `next_bd` as a "jump" to the next BB which contains a `dma_bd`). - - Example: - ``` - // this defines a BD that uses lock %lck0 and buffer %buf0 - ^bd5: - aie.use_lock(%lck, "Acquire", 0) - // transfer the first 32 elements of the memref - aie.dma_bd(<$buf0 : memref<128xi32>, 0, 32) - aie.use_lock(%lck, "Release", 1) - aie.next_bd ^bd6 // point to the next bb, which describes the next buffer descriptor - ^bd6: - aie.use_lock(%lck, "Acquire", 1) - // transfer the last 32 elements of the memref - aie.dma_bd(<$buf1 : memref<128xi32>, 96, 32) - aie.use_lock(%lck, "Release", 0) - aie.next_bd ^end - - ... - - // this defines a BD that does not use any lock - ^bd8: - aie.dma_bd(<$buf2 : memref<64xi32>, 0, 64) - ``` - - #### Background/context - - A DMA channel in a Memory Module can process one buffer descriptor after another by chaining them. - There are 16 buffer descriptors per Core memory module and 48 buffer descriptors per Memtile memory module. - They are shared by four DMA channels (or 12). - - #### DMA Data Layout Transformations on AIE-ML Devices - - AIE-ML devices can apply data layout transformations at the buffer - descriptor level. These transformation are described by strides and sizes in up to three dimensions (four - dimensions on memtiles). Strides and sizes can be supplied to the `dma_bd` - through an optional argument, an array of "tuple-like" attributes `bd_dim_layout`. - - The first element of this array gives the outer-most dimension's stride and - size, the last element of the array gives the inner-most dimension's stride and size. - We can model the access pattern strides and sizes generate by a series of - nested loops. In general, a set of strides and sizes like this... - - ``` - [, , ] - ``` - - ...translates to an access pattern that can be epxressed like this: - - ``` - int *buffer; // i32 - for(int i = 0; i < size_2; i++) - for(int j = 0; j < size_1; j++) - for(int k = 0; k < size_0; k++) - // 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: - - ``` - aie.dma_bd(%buf : memref<128xi32>, 0, 128, [<8, 16>, <2, 1>, <8, 2>]) - ``` - - implies - - ``` - for(int i = 0; i < 8 /*size_2*/; i++) - for(int j = 0; j < 2 /*size_1*/; j++) - for(int k = 0; k < 8 /*size_0*/; k++) - // access/store element at/to index (i * 16 /*stride_2*/ + j * 1 /*stride_1*/ + k * 2 /*stride_0*/) - ``` - - #### Important gotcha regarding strides - - All strides are expressed in multiples of the element width (just like `len` and `offset`) - **with the caveat that the inner-most dimension's stride must be 1**. - - ## DMA constant padding on AIE-ML Devices - - AIE-ML devices can apply constant padding at the buffer descriptor level, described with pairs of padding - counts before and after a dimension, to all dimensions in the data layout transformations. The padding - counts can be supplied to the `dma_bd` through an optional argument, an array of "tuple-like" attributes - `bd_pad_layout`, followed by an optional argument `const_val` (default - is 0). All counts are expressed in multiples of the element width. - }]; - let arguments = ( ins AnyMemRef:$buffer, // in multiples of element width (not bytes) @@ -772,29 +364,6 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [ ]>, Results<(outs I1:$valid)> { let summary = "An op to start DMA"; - let description = [{ - This operation declares a DMA channel to be used for data transfer. It usually exists inside - either a MemOp (representing a TileDMA), a MemTileDMAOp (representing a DMA in a MemTile), - or in a ShimDMAOp (representing a ShimDMA). - A channel is defined by a direction (i.e., MM2S or S2MM) and an index. - - Example: - ``` - aie.dma_start("MM2S", 0, ^bd0, ^end) - ^bd0: - aie.use_lock(%lock0, "Acquire", 0) - aie.dma_bd(%buffer : memref<16 x f32>, 0, 16) - aie.use_lock(%lock0, "Release", 1) - br ^bd0 - ^end: - aie.end - ``` - - Conceptually, the aie.dma_start operation is a terminator that either passes - control to a basic block containing DMA operations (through its first successor) - or to a basic block for another dma_start, to an aie.end operation. - }]; - let arguments = ( ins DMAChannelDir:$channel_dir, ConfinedAttr]>:$channel_index, @@ -846,32 +415,10 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [ // 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, - IsCoreTile, HasValidBDs, HasValidDMAChannels, + CallableOpInterface, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a memory op"; - let description = [{ - This operation creates a Memory module that belongs to a tile. - The region of a MemOp is used to setup the DMAs and Block Descriptors. - See DMAStartOp and DMABdOp for more concrete examples on DMAs and Block Descriptors. - - Example: - ``` - m73 = aie.mem(%t73) { - %srcDma = aie.dma_start("S2MM", 0, ^bd0, ^end) - ^bd0: - aie.use_lock(%lock, "Acquire", 0) - aie.dma_bd(%buf : memref<64xi16>, 0, 64) - aie.use_lock(%lock, "Release", 1) - aie.next_bd ^bd0 - ^end: - aie.end - } - ``` - Create the memory module for tile %t73 and setup one DMA channel and one Buffer Descriptor. - }]; - let arguments = (ins Index:$tile); let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; @@ -885,36 +432,10 @@ def AIE_MemOp: AIE_Op<"mem", [ // This op is not actually Callable, but we want to inline code into them, so we have to // implement CallableOpInterface def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ - TileElement, FlowEndPoint, CallableOpInterface, - IsMemTile, HasValidBDs, HasValidDMAChannels, + CallableOpInterface, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a memtile_dma op"; - let description = [{ - This operation describes a DMA inside an AIE2 MemTile. - The region of the op is used to setup the DMAs and Block Descriptors. - See DMAStartOp and DMABdOp for more concrete examples on DMAs and Block Descriptors. - - This operation is restricted to certain compatible tiles in AIE2 devices: - xcve2302: row 1 - xcve2802: row 1 and 2 - - Example: - ``` - m73 = aie.memtile_dma(%t71) { - %srcDma = aie.dma_start("S2MM", 0, ^bd0, ^end) - ^bd0: - aie.use_lock(%lock, "Acquire", 0) - aie.dma_bd(%buf : memref<64xi16>, 0, 64>, 0) - aie.use_lock(%lock, "Release", 1) - aie.next_bd ^bd0 - ^end: - aie.end - } - ``` - Create a description for tile `%t73` and setup one DMA channel and one Buffer Descriptor. - }]; - let arguments = (ins Index:$tile); let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; @@ -929,27 +450,6 @@ def AIE_NextBDOp: AIE_Op<"next_bd", [ Terminator, ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp"]> ]> { let summary = "The next buffer descriptor"; - let description = [{ - This operation terminates the basic block describing a buffer descriptor inside - a tile or shim DMA operation. It references a single following buffer descriptor. - Note that unlike other terminators (like cf.br), canonicalization should not remove - the `next_bd` terminator, since it would result in invalid buffer descriptors. - - Example: - ``` - m73 = aie.mem(%t73) { - %srcDma = aie.dma_start("S2MM", 0, ^bd0, ^end) - ^bd0: - aie.use_lock(%lock, "Acquire", 0) - aie.dma_bd(%buf : memref<64xi16>, 0, 64) - aie.use_lock(%lock, "Release", 1) - aie.next_bd ^bd0 - ^end: - aie.end - } - ``` - }]; - let successors = (successor AnySuccessor:$dest); let assemblyFormat = [{ @@ -962,22 +462,6 @@ def AIE_LockOp: AIE_Op<"lock", [ DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a physical lock"; - let description = [{ - This operation creates a physical lock. For this operation the lockID variable is optional. - However, if that is the case then the lockID must be assigned using the AIEAssignLockIDs pass. - - Example: - ``` - %tile33 = aie.tile(3, 3) - %lck = aie.lock(%tile33, 7) - ``` - This operation represents a lock that lives in the Memory module of Tile(3, 3) with a lockID of 7 - - Case when LockID is not assigned: - Before AIEAssignLockIDs: `%tile33 = aie.tile(3)` - After AIEAssignLockIDs: `%tile33 = aie.tile(3, $assigned_value)` - }]; - let arguments = ( ins Index:$tile, OptionalAttr]>>:$lockID, @@ -996,8 +480,8 @@ def AIE_LockOp: AIE_Op<"lock", [ std::string nameWithoutDialect = getOperationName().str().substr(getOperationName().find('.') + 1); setNameFn(getResult(), nameWithoutDialect + "_" + - std::to_string(getTileID().col) + "_" + - std::to_string(getTileID().row)); + std::to_string(getTileLoc().col) + "_" + + std::to_string(getTileLoc().row)); } } }]; @@ -1018,15 +502,6 @@ def AIE_LockOp: AIE_Op<"lock", [ def AIE_UseLockOp: AIE_Op<"use_lock", []> { let summary = "acquire/release lock op"; - let description = [{ - This operation uses a lock. In AIE1, a lock can be acquired with a value, - or released with a value. This should be understood as a "blocking" - operation. In AIE2, locks are counting semaphores without inherent - acquired/release characteristic. This lock must appear in a parent op where - the tile can be determined (A CoreOp, a ShimDMAOp, a MemOp, or a - MemTileDMAOp). - }]; - let arguments = ( ins Index:$lock, LockAction:$action, @@ -1050,20 +525,9 @@ def AIE_UseLockOp: AIE_Op<"use_lock", []> { } def AIE_BufferOp: AIE_Op<"buffer", [ - TileElement, IsTileWithMemory + TileElement ]>, Results<(outs AnyMemRef)> { let summary = "Declare a buffer"; - let description = [{ - This operation instantiates a buffer that belongs to a Memory Module of a tile. - - Example: - ``` - %tile33 = aie.tile(3, 3) - %buf = aie.buffer(%tile33) : memref<256xi64> - ``` - This operation represents a buffer in tile (3, 3) of 256 elements, each a 64-bit integer. - }]; - let arguments = ( ins Index:$tile, OptionalAttr:$sym_name, @@ -1086,8 +550,8 @@ def AIE_BufferOp: AIE_Op<"buffer", [ std::string nameWithoutDialect = getOperationName().str().substr(getOperationName().find('.') + 1); setNameFn(getResult(), nameWithoutDialect + "_" + - std::to_string(getTileID().col) + "_" + - std::to_string(getTileID().row)); + std::to_string(getTileLoc().col) + "_" + + std::to_string(getTileLoc().row)); } }]; } @@ -1096,23 +560,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ DeclareOpInterfaceMethods ]>, Results<(outs AnyMemRef)> { let summary = "Declare a buffer in external memory"; - let description = [{ - This operation represents a buffer that exists in some physical - location in a device, most likely external memory. The exact address - of the external buffer is passed by the mlir_aie_external_set_addr() - and mlir_aie_external_set_addr_myBuffer_ functions in the associated - .cpp test file. - - These external buffers are used within the buffer descriptors of a - shim_dma, i.e., within AIE_DMABdOp operations of a AIE_ShimDMAOp. - - Example: - ``` - %buf = aie.external_buffer : memref<256xi64> - ``` - This operation represents an external buffer. - }]; - let arguments = (ins OptionalAttr:$sym_name); let results = (outs AnyMemRef:$buffer); @@ -1129,9 +576,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ // def AIE_EventOp: AIE_Op<"event", []> { // let summary = "Event instruction"; -// let description = [{ -// Event instruction. -// }]; // let arguments = (ins ConfinedAttr, IntMaxValue<1>]>:$val); // let results = (outs); // let assemblyFormat = [{ @@ -1143,10 +587,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ // HasParent<"CoreOp"> // ]>, Results<(outs AnyTypeOf<[F32, I32, I<128>]>)> { // let summary = "An op to read from a stream channel/port of a switchbox"; -// let description = [{ -// An op to read from a stream channel/port of a switchbox. -// }]; -// // let arguments = (ins AnyInteger:$channel); // let results = (outs AnyTypeOf<[F32, I32, I<128>]>:$stream_value); // @@ -1164,10 +604,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ // // def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { // let summary = "An op to write to a stream channel/port of a switchbox"; -// let description = [{ -// An op to write to a stream channel/port of a switchbox. -// }]; -// // let arguments = ( // ins AnyInteger:$channel, // AnyTypeOf<[F32, I32, I<128>]>:$stream_value @@ -1191,18 +627,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ // Index:$dest_tile // ); // let summary = "A cascade connection between tiles"; -// let description = [{ -// The `aie.cascade_flow` operation represents a cascade connection between two `aie.tile` operations. -// During lowering, this is replaced by `aie.configure_cascade` operations for each `aie.tile` based on -// their relative placement to one another. -// -// Example: -// ``` -// %tile03 = aie.tile(0, 3) -// %tile13 = aie.tile(1, 3) -// aie.cascade_flow(%tile03, %tile13) -// ``` -// }]; // let hasVerifier = 1; // let assemblyFormat = [{ // `(` $source_tile `,` $dest_tile `)` attr-dict @@ -1215,17 +639,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ // // def AIE_ConfigureCascadeOp: AIE_Op<"configure_cascade", [HasParent<"DeviceOp">]> { // let summary = "An op to configure the input and output directions of the cascade for a single AIE tile"; -// let description = [{ -// An operation to configure the cascade on a single tile in both the input and the output -// directions. -// -// Example: -// ``` -// %tile00 = aie.tile(1, 3) -// aie.configure_cascade(%tile00, West, East) -// ``` -// Configures the input cascade port of %tile00 to the West direction, and the output port to the East direction. -// }]; // let arguments = ( // ins Index:$tile, // CascadeDir:$inputDir, @@ -1238,23 +651,12 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ // // def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascade_value)> { // let summary = "An op to read from a cascading stream from a neighboring core"; -// let description = [{ -// An op to read from a cascading stream from a neighboring core. -// The result type of this operation must have a size that matches the cascade size, -// which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> -// }]; // let hasVerifier = 1; // let assemblyFormat = [{ `(` `)` attr-dict `:` type($cascade_value) }]; // } // // def AIE_PutCascadeOp: AIE_Op<"put_cascade", [HasParent<"CoreOp">]> { // let summary = "An op to write to a cascading stream from a neighboring core"; -// let description = [{ -// An op to write to a cascading stream from a neighboring core. -// The argument type of this operation must have a size that matches the cascade size, -// which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32> -// }]; -// // let arguments = (ins AnyType:$cascade_value); // let hasVerifier = 1; // let assemblyFormat = [{ `(` $cascade_value `:` type($cascade_value) `)` attr-dict }]; @@ -1262,27 +664,6 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp">]> { let summary = "Runtime allocation information for a single shim DMA"; - let description = [{ - This op exists for cases where shim_dma configuration is performed outside of MLIR-AIE - and hence there is no appropriate dma_start operation to indicate which channel is being - used and on which column the shim_dma is. - - It contains attributes for the sym_name of an operation which generated the shim DMA, - for the DMAChannelDir and channel index, and for the column of the shim tile to which - the originating operation was mapped. - - Example: - ``` - %tile00 = aie.tile(0, 0) - %tile02 = aie.tile(0, 2) - aie.objectfifo @of_in_0 (%tile00, { %tile02 }, 2) : !aie.objectfifo> - ``` - could produce the following allocation info (channel direction MM2S, channel index 1, and shim column 0): - ``` - aie.shim_dma_allocation @of_in_0 (MM2S, 1, 0) - ``` - }]; - let arguments = ( ins FlatSymbolRefAttr:$sym_name, DMAChannelDir:$channel_dir, @@ -1301,82 +682,6 @@ def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]> { let summary = "Create a circular buffer or channel between two tiles"; - let description = [{ - The `aie.objectFifo` operation creates a circular buffer established between a producer and one or - more consumers, which are `aie.tile` operations. The`aie.objectFifo` instantiates the given number of - buffers (of given output type) and their locks in the Memory Module of the appropriate tile(s) after - lowering, based on tile-adjacency. These elements represent the conceptual depth of the `objectFifo` or, - more specifically, of its object pool. - - For the producer and for each consumer, a different size (i.e., element number) can be specified as an - array of integer values. This will take effect in the case of consumers placed on tiles non-adjacent to - the producer. Otherwise, the producer size will be applied. If a single size is specified, it will be - applied to both producer and consumers. - - This operation is then converted by the `AIEObjectFifoStatefulTransformPass` into `aie.buffers` and their associated - `aie.locks`. The pass also establishes Flow and DMA operations between the producer and consumer tiles if they are - not adjacent. - - 1-to-1 tile example: - ``` - aie.objectfifo @of1 (%tile12, { %tile23 }, 4 : i32) : !aie.objectfifo> - ``` - This operation creates an `objectFifo` between `%tile12` and `%tile23` of 4 elements, each a buffer of 16 32-bit integers. - Note: If there are no `ObjectFifoAcquireOps` corresponding to this `objectFifo` on the cores of `%tile12` and `%tile23`, - then the depths of the object pools on each tile will be 4, as specified. Otherwise, the cores are scanned and the - highest number of acquired elements (+1 for prefetching) will be used instead, to ensure minimal resource usage. - - 1-to-2 tiles broadcast example: - ``` - aie.objectfifo @of2 (%tile12, { %tile13, %tile23 }, 4 : i32) : !aie.objectfifo> - ``` - This operation creates an `objectFifo` between `%tile12` and tiles `%tile13`, `%tile23` of 4 elements, each a buffer of x16 - 32-bit integers. - - 1-to-2 tiles broadcast with explicit sizes example: - ``` - aie.objectfifo @of3 (%tile12, { %tile13, %tile23 }, [2, 3, 4]) : !aie.objectfifo> - ``` - This operation creates an `objectFifo` between `%tile12`, `%tile13` and `%tile23`. The depths of the `objectFifo` object pool - at each tile are respectively 2, 3 and 4 for tiles `%tile12`, `%tile13` and `%tile23`. This overrides the depth analysis - specified in the first example. - - #### Data Layout Transformations on AIE-ML devices - - On AIE-ML devices, objectFifos can also apply data layout transformations by - using the DMAs n-dimensional address generation scheme. Two transformations - can be applied for an objectFifo: one on the producer side, given by a - `toStream` attribute, and one transformation on the consumer side, given by - a `fromStream` attribute. See the `DMABDOp` documentation for a description - of strides and sizes. The `toStream` and `fromStream` optional attributes - are given directly following the producer or consumer tile declaration. - Different transformations can be specified for each consumer. See example - below. - - Note that using data layout transformations will cause the DMA be used even - between adjacent tiles whose objectFifos would otherwise use shared memory. - - Further note that data layout transforms always apply at a granularity of - `i32`s, irrespective of the used `memref` data type. This is an - architectural requirement. Hence, a stride of 4 always expresses 4 `i32`s, - i.e. 16 bytes. - - The following example shows an objectFifo which transposes a 16x16 matrix of - `i32`s on the producer side using strides and sizes. No transformation is - applied on the consumer side of `%tile13` (in this case the `fromStream` - attribute may also be left off), and a transformation on `%tile23` first gives - all even indices from the stream, followed by all odd indices: - - ``` - aie.objectfifo @of4 (%tile12 toStream [<16, 1>, <16, 16>, <1,1>], - { - %tile13 fromStream [], - %tile23 fromStream [<2, 1>, <128, 2>] - }, 2 : i32 - ) : !aie.objectfifo> - ``` - }]; - let arguments = ( ins SymbolNameAttr:$sym_name, Index:$producerTile, @@ -1423,29 +728,6 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { let summary = "Links two objectFifos through an intermediary tile's DMA"; - let description = [{ - The `aie.objectFifo.link` operation allows to mark two `objectFifos` as linked. This implies that the two `objectFifos` form - one dataflow movement which is split accross multiple `objectFifos`. Specifically, during the `objectFifo` lowering there will - be less memory elements generated at the link point as the two `objectFifos` can share. - - The two `objectFifos` which are linked must have a link point (i.e., a shared AIE tile). - In L1, only `objectFifos` of same size may be linked. In L2, different sized objectFifos can be linked. - - Example: - ``` - aie.objectfifo @of1 (%t70, { %t72 }, 2) : !aie.objectfifo> - aie.objectfifo @of2 (%t72, { %t74 }, 2) : !aie.objectfifo> - aie.objectfifo.link [@of1] -> [@of2] () - ``` - This operation links two `objectFifos` which have tile `%t72` as a link point. - - To achieve a broadcast pattern through the link tile, the output `objectFifo` should have a list of all the consumers tiles. - To achieve a distribute pattern from the link tile, there should be multiple output `objectFifos` in the LinkOp. In this case, - parts will be taken out of the input `objectFifo`'s buffers based on the sizes of the output `objectFifos`, in the order they - were given in the LinkOp. - The join pattern is the exact inverse of the distribute one. - }]; - let arguments = ( ins SymbolRefArrayAttr:$fifoIns, SymbolRefArrayAttr:$fifoOuts @@ -1461,26 +743,9 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { } def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_external_buffers", [ - HasParent<"DeviceOp">, TileElement, IsShimNOCTile + HasParent<"DeviceOp">, TileElement ]> { let summary = "Registers external buffers to given object fifo shim tile(s) to use in the associated shim DMA(s)"; - let description = [{ - The `aie.objectfifo.register_external_buffers` operation is used to register one or multiple external buffers - to the shim tile(s) used in an `objectFifo` creation. During the `objectFifo` lowering pass, shim DMAs that are - generated for those shim tiles will use the registered external buffers. This is currently done because - external buffers typically have a different size than the AIE buffers which are used in the AIE tiles of the - same `objectFifos`. - - Example: - ``` - aie.objectfifo @of1 (%t70, %t73, 2) : !aie.objectfifo> - %buffer_in_0 = aie.external_buffer : memref<512 x i16> - %buffer_in_1 = aie.external_buffer : memref<512 x i16> - aie.objectfifo.register_external_buffers @of1 (%t70, {buffer_in_0, buffer_in_1}) : (memref<512 x i16>, memref<512 x i16>) - ``` - This operation registers external buffers `%buffer_in_0` and `%buffer_in_1` to use in the shim_dma of shimTile `%t70`. - }]; - let arguments = ( ins FlatSymbolRefAttr:$objFifo_name, Index:$tile, @@ -1501,27 +766,6 @@ def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_externa def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { let summary = "Acquire operation to lock and return objects of an ObjectFifo"; - let description = [{ - The `aie.objectFifo.acquire` operation first acquires the locks of the next given number - of objects in the `objectFifo`. The mode it acquires the locks in is chosen based on the port - (producer: acquire for write, consumer: acquire for read). Then, it returns a subview of - the acquired objects which can be used to access them. - - This operation is then converted by the `AIEObjectFifoStatefulTransformPass` into `aie.use_lock` operations on - the locks of the `objectFifo` objects that will be acquired. Under the hood, the operation only performs - new acquires if necessary. For example, if two objects have been acquired in the past and none have yet - to be released by the same process, then performing another acquire operation on the same `objectFifo` - within the same process of size two or less will not result in any new use_lock operations (and for size - greater than two, only (size - 2) use_lock operations will be performed). - - Example: - ``` - %subview = aie.objectfifo.acquire @of1 (Consume, 2) : !aie.objectfifosubview> - ``` - This operation acquires the locks of the next two objects in the `objectFifo` named `@of1` from its consumer - port and returns a subview of the acquired objects. - }]; - let arguments = ( ins ObjectFifoPort:$port, FlatSymbolRefAttr:$objFifo_name, @@ -1539,20 +783,6 @@ def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { let summary = "Release operation for object locks in an ObjectFifo"; - let description = [{ - The `aie.objectFifo.release` operation releases the locks of the given number of objects - in the `objectFifo`. The mode it releases the locks in is chosen based on the `port` - (producer: release for read, consumer: release for write). - - This operation is then converted by the `AIEObjectFifoStatefulTransformPass` into `aie.use_lock` operations. - - Example: - ``` - aie.objectfifo.release @of1 (Produce, 1) - ``` - This operation releases the lock of the next object in the `objectFifo` named `@of1` from producer port. - }]; - let arguments = ( ins ObjectFifoPort:$port, FlatSymbolRefAttr:$objFifo_name, @@ -1568,19 +798,6 @@ def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { let summary = "ObjectFifoSubview type accessor method"; - let description = [{ - Access the Nth element of a value of `ObjectFifoSubview` type. - - Example: - ``` - %subview = aie.objectfifo.acquire @of1 (Produce, 3) : !aie.objectfifosubview> - %elem = aie.objectfifo.subview.access %subview[0] : !aie.objectfifosubview> -> memref<16xi32> - ``` - In this example, `%elem` is the first object of the subview. Note that this may not correspond to the first element of - the `objectFifo` if other acquire operations took place beforehand. - - }]; - let arguments = ( ins AIE_ObjectFifoSubviewType:$subview, ConfinedAttr]>:$index @@ -1602,31 +819,6 @@ def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { // def AIE_ObjectFifoRegisterProcessOp: AIE_Op<"objectfifo.register_process", []> { // let summary = "Operation that produces the acquire/release patterns for a process registered to an objectFifo"; -// let description = [{ -// The `aie.registerProcess` operation allows the user to register a function to an `objectFifo` along with its -// acquire and release patterns. These patterns will be used to generate a sequence of acquires and releases -// on the `objectFifo` elements. This generated sequence is often in the form of a for loop, however, in the case -// of cyclo-static patterns only the repetition of same number accesses and releases will generate a for loop. -// This may result in multiple for loops of different sizes being generated. If there is no repetition, then no -// loops will be generated. -// -// Example: -// ``` -// aie.objectfifo @of1 (%t72, %t73, 2) : !aie.objectfifo> -// %length = arith.constant 10 : index -// %acquirePatternProducer = arith.constant dense<[1, 2, 2, 0]> : tensor<4xi32> -// %releasePatternProducer = arith.constant dense<[0, 1, 1, 2]> : tensor<4xi32> -// func @producer_work(%input : !aie.objectfifosubview>) -> () { ... } -// -// aie.objectfifo.register_process @of1 (Produce, %acquirePatternProducer : tensor<4xi32>, %releasePatternProducer : tensor<4xi32>, @producer_work, %length) -// ``` -// This operation registers function @producer_work and associated patterns to the produce end of @of1. -// @producer_work will be called with the subviews produced when acquiring elements from @of1 following the acquire pattern. -// -// If the input patterns are static (only one element) then the length of the produced for loop will be that of the input `%length`. -// If the input patterns are cyclo-static then they must be of the same size. -// }]; -// // let arguments = ( // ins ObjectFifoPort:$port, // FlatSymbolRefAttr:$objFifo_name, diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp index 3ff8d9a83..8c3d7362a 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp @@ -38,8 +38,8 @@ LogicalResult assignBdIds(DeviceOp deviceOp) { llvm::append_range(memOps, deviceOp.getOps()); llvm::append_range(memOps, deviceOp.getOps()); for (TileElement memOp : memOps) { - int col = memOp.getTileID().col; - int row = memOp.getTileID().row; + int col = memOp.getTileLoc().col; + int row = memOp.getTileLoc().row; // BdIdGenerator gen(col, row, deviceModel); ChannelBdIdGenerator gen = deviceModel.isMemTile(col, row) diff --git a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt index f267ee086..ce9a70ad1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt @@ -77,8 +77,8 @@ iree_cc_library( AIEDialectIR SRCS AIEDialect.cpp - AIETargetModel.cpp DEPS + iree-amd-aie::aie_runtime::iree_aie_runtime_static ::AIEAttrsGen ::AIEDialectGen ::AIEInterfacesGen From df6783b684d076bbe5d99b184843355d08c56473 Mon Sep 17 00:00:00 2001 From: max Date: Sun, 4 Aug 2024 10:12:05 -0500 Subject: [PATCH 04/12] remove types --- .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 1907 ----------------- .../plugins/target/AMD-AIE/aie/AIETypes.td | 41 - 2 files changed, 1948 deletions(-) delete mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETypes.td diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index 4cdba7b7c..2fd513843 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -27,351 +27,8 @@ using namespace xilinx::AIE; // We implement the initialize() function further below #include "aie/AIEDialect.cpp.inc" -namespace { - -struct AIEInlinerInterface : DialectInlinerInterface { - using DialectInlinerInterface::DialectInlinerInterface; - // We don't have any special restrictions on what can be inlined into - // destination regions. Always allow it. - bool isLegalToInline(Region *dest, Region *src, bool wouldBeCloned, - IRMapping &valueMapping) const final override { - return true; - } - - // Operations in aie dialect are always legal to inline since they are - // pure. - bool isLegalToInline(Operation *op, Region *, bool wouldBeCloned, - IRMapping &) const final override { - return true; - } - - // Handle the given inlined terminator by replacing it with a new operation - // as necessary. Required when the inlined region has more than one block. - void handleTerminator(Operation *op, Block *newDest) const final override {} - - // Handle the given inlined terminator by replacing it with a new operation - // as necessary. Required when the region has only one block. - void handleTerminator(Operation *op, - ValueRange valuesToRepl) const final override {} -}; - -struct AIEDialectFoldInterface : DialectFoldInterface { - using DialectFoldInterface::DialectFoldInterface; - - /// Registered hook to check if the given region, which is attached to an - /// operation that is *not* isolated from above, should be used when - /// materializing constants. - bool shouldMaterializeInto(Region *region) const final override { - // If this is an AIE::CoreOp region, then insert into it. - return isa(region->getParentOp()); - } -}; - -} // end anonymous namespace - namespace xilinx::AIE { - -LogicalResult myVerifyOffsetSizeAndStrideOp(OffsetSizeAndStrideOpInterface op) { - std::array maxRanks = op.getArrayAttrMaxRanks(); - if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) && // NOLINT - op.getMixedOffsets().size() != op.getMixedSizes().size()) - return op->emitError( - "expected mixed offsets rank to match mixed sizes rank (") - << op.getMixedOffsets().size() << " vs " << op.getMixedSizes().size() - << ") so the rank of the result type is well-formed."; - if (failed(verifyListOfOperandsOrIntegers( - op, "offset", maxRanks[0], op.getStaticOffsets(), op.getOffsets()))) - return failure(); - if (failed(verifyListOfOperandsOrIntegers( - op, "size", maxRanks[1], op.getStaticSizes(), op.getSizes()))) - return failure(); - if (failed(verifyListOfOperandsOrIntegers( - op, "stride", maxRanks[2], op.getStaticStrides(), op.getStrides()))) - return failure(); - for (int64_t offset : op.getStaticOffsets()) - if (offset < 0 && !ShapedType::isDynamic(offset)) - return op->emitError("expected offsets to be non-negative, but got ") - << offset; - for (int64_t size : op.getStaticSizes()) - if (size < 0 && !ShapedType::isDynamic(size)) - return op->emitError("expected sizes to be non-negative, but got ") - << size; - - return success(); -} - -static VC1902TargetModel VC1902model; -static VE2302TargetModel VE2302model; -static VE2802TargetModel VE2802model; -static NPUTargetModel NPUmodel; -static VirtualizedNPUTargetModel NPUmodel1col(1); -static VirtualizedNPUTargetModel NPUmodel2col(2); -static VirtualizedNPUTargetModel NPUmodel3col(3); -static VirtualizedNPUTargetModel NPUmodel4col(4); - -const AIETargetModel &getTargetModel(Operation *op) { - if (auto t = dyn_cast(op)) return t.getTargetModel(); - if (auto t = op->getParentOfType()) return t.getTargetModel(); - - // For backward compatibility, return a basic device model compatible with - // the VCK190 - return VC1902model; -} - -const AIETargetModel &getTargetModel(AIEDevice device) { - switch (device) { - case AIEDevice::xcvc1902: - return VC1902model; - case AIEDevice::xcve2302: - return VE2302model; - case AIEDevice::xcve2802: - return VE2802model; - case AIEDevice::npu1: - return NPUmodel; - case AIEDevice::npu1_1col: - return NPUmodel1col; - case AIEDevice::npu1_2col: - return NPUmodel2col; - case AIEDevice::npu1_3col: - return NPUmodel3col; - case AIEDevice::npu1_4col: - return NPUmodel4col; - } - return VC1902model; -} - -// Walk the operation hierarchy until we find a containing TileElement. -// If no parent is a TileElement, then return null. -static TileElement getParentTileElement(Operation *op) { - auto *parent = op->getParentOp(); - while (!llvm::isa_and_nonnull(parent)) { - if (auto element = llvm::dyn_cast(parent)) return element; - parent = parent->getParentOp(); - } - return llvm::dyn_cast(parent); -} - -struct UsesAreAccessable { - static LogicalResult verifyTrait(Operation *op) { - auto thisElement = cast(op); - auto thisID = thisElement.getTileLoc(); - auto users = op->getResult(0).getUsers(); - const auto &targetModel = getTargetModel(op); - for (auto *user : users) { - // AIE.useLock may be used in a device to set the lock's default value - // Allow in a toplevel module for backward compatibility - if (llvm::isa_and_nonnull(user->getParentOp())) - return success(); - if (auto element = getParentTileElement(user)) { - auto TileLoc = element.getTileLoc(); - if (!targetModel.isLegalMemAffinity(TileLoc.col, TileLoc.row, thisID.col, - thisID.row)) - return (op->emitOpError("in Column ") - << thisID.col << " and Row " << thisID.row - << " is accessed from an unreachable tile in Column " - << TileLoc.col << " and Row " << TileLoc.row) - .attachNote(user->getLoc()) - << "user"; - } else { - // This should probably be caught elsewhere as well. - return op->emitOpError("is accessed outside of a tile") - .attachNote(user->getLoc()) - << "user"; - } - } - return success(); - } -}; - -namespace detail { -/// This class represents the internal storage of the AIE `ObjectFifoType`. -struct AIEObjectFifoTypeStorage : TypeStorage { - /// The `KeyTy` is a required type that provides an interface for the storage - /// instance. This type will be used when uniquing an instance of the type - /// storage. - using KeyTy = MemRefType; - - /// A constructor for the objectFifo type storage instance. - AIEObjectFifoTypeStorage(MemRefType elementType) : elementType(elementType) {} - - /// Define the comparison function for the key type with the current storage - /// instance. This is used when constructing a new instance to ensure that we - /// haven't already uniqued an instance of the given key. - bool operator==(const KeyTy &key) const { return key == KeyTy(elementType); } - - /// Define a construction method for creating a new instance of this storage. - /// This method takes an instance of a storage allocator, and an instance of a - /// `KeyTy`. - static AIEObjectFifoTypeStorage *construct(TypeStorageAllocator &allocator, - const KeyTy &key) { - // Allocate the storage instance and construct it. - return new (allocator.allocate()) - AIEObjectFifoTypeStorage(key); - } - - MemRefType elementType; -}; -} // namespace detail - -AIEObjectFifoType AIEObjectFifoType::get(MemRefType elementType) { - // Call into a helper 'get' method in 'TypeBase' to get an uniqued instance - // of this type. - MLIRContext *ctx = elementType.getContext(); - return Base::get(ctx, elementType); -} - -LogicalResult AIEObjectFifoType::verify( - function_ref emitError, MemRefType elementType) { - return success(); -} - -mlir::MemRefType AIEObjectFifoType::getElementType() { - // 'getImpl' returns a pointer to the internal storage instance. - return getImpl()->elementType; -} - -namespace detail { -/// This class represents the internal storage of the AIE -/// `ObjectFifoSubviewType`. -struct AIEObjectFifoSubviewTypeStorage : TypeStorage { - /// The `KeyTy` is a required type that provides an interface for the storage - /// instance. This type will be used when uniquing an instance of the type - /// storage. - using KeyTy = MemRefType; - - /// A constructor for the subview type storage instance. - AIEObjectFifoSubviewTypeStorage(MemRefType elementType) - : elementType(elementType) {} - - /// Define the comparison function for the key type with the current storage - /// instance. This is used when constructing a new instance to ensure that we - /// haven't already uniqued an instance of the given key. - bool operator==(const KeyTy &key) const { return key == elementType; } - - /// Define a construction method for creating a new instance of this storage. - /// This method takes an instance of a storage allocator, and an instance of a - /// `KeyTy`. - static AIEObjectFifoSubviewTypeStorage *construct( - TypeStorageAllocator &allocator, const KeyTy &key) { - // Allocate the storage instance and construct it. - return new (allocator.allocate()) - AIEObjectFifoSubviewTypeStorage(key); - } - - MemRefType elementType; -}; -} // namespace detail - -AIEObjectFifoSubviewType AIEObjectFifoSubviewType::get(MemRefType elementType) { - // Call into a helper 'get' method in 'TypeBase' to get a uniqued instance - // of this type. - MLIRContext *ctx = elementType.getContext(); - return Base::get(ctx, elementType); -} - -/// This method is used to verify the construction invariants. -LogicalResult AIEObjectFifoSubviewType::verify( - function_ref emitError, MemRefType elementType) { - return success(); -} - -MemRefType AIEObjectFifoSubviewType::getElementType() { - return getImpl()->elementType; -} - -/// Parse an instance of a type registered to the AIE dialect. -/// Parse an AIE type in the following forms: -/// AIE-type -/// ::= `objectfifo` `<` type `>` -/// ::= `objectfifosubview` `<` type `>` -static OptionalParseResult aieTypeParser(DialectAsmParser &parser, - StringRef name, Type &result) { - if (name == "objectfifo") { - MemRefType elementType; - SMLoc typeLoc = parser.getCurrentLocation(); - if (parser.parseLess() || parser.parseType(elementType) || - parser.parseGreater()) - return failure(); - - // Check that the type is a MemRef type. - if (!llvm::isa(elementType)) { - parser.emitError(typeLoc, - "element type for an objectFifo must be " - "a MemRefType, got: ") - << elementType; - return failure(); - } - - return result = AIEObjectFifoType::get(elementType), success(); - } - - if (name == "objectfifosubview") { - if (parser.parseLess()) return failure(); - - // Parse the element type of the struct. - MemRefType elementType; - // Parse the current element type. - SMLoc typeLoc = parser.getCurrentLocation(); - if (parser.parseType(elementType)) return failure(); - - // Check that the type is a MemRefType. - if (!llvm::isa(elementType)) { - parser.emitError(typeLoc, - "element type for a subview must be " - "a MemRefType, got: ") - << elementType; - return failure(); - } - - // Parse: `>` - if (parser.parseGreater()) return failure(); - - return result = AIEObjectFifoSubviewType::get(elementType), success(); - } - - return {}; -} - -/// Parse a type defined by this dialect. -/// Emits an error and returns failure if `name` does not -/// refer to a type defined in this dialect. -static ParseResult parse(Type &result, StringRef name, - DialectAsmParser &parser) { - if (OptionalParseResult parseResult = aieTypeParser(parser, name, result); - parseResult.has_value()) - return parseResult.value(); - - parser.emitError(parser.getNameLoc(), "unknown AIE dialect type: \"") - << name << "\""; - return failure(); -} - -/// Parse an instance of a type registered to the AIE dialect. -Type AIEDialect::parseType(DialectAsmParser &parser) const { - StringRef name; - Type result; - if (parser.parseKeyword(&name) || parse(result, name, parser)) return {}; - return result; -} - -/// Print an instance of a type registered to the AIE dialect. -void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { - if (llvm::isa(type)) { - auto objectFifoType = llvm::cast(type); - printer << "objectfifo<"; - printer << objectFifoType.getElementType(); - printer << '>'; - - } else if (llvm::isa(type)) { - auto subviewType = llvm::cast(type); - printer << "objectfifosubview<"; - printer << subviewType.getElementType(); - printer << '>'; - } -} - void AIEDialect::initialize() { - addTypes(); addAttributes< #define GET_ATTRDEF_LIST #include "aie/AIEAttrs.cpp.inc" @@ -380,1579 +37,15 @@ void AIEDialect::initialize() { #define GET_OP_LIST #include "aie/AIEOps.cpp.inc" >(); - addInterfaces(); } - } // namespace xilinx::AIE -// Check that the operation only contains terminators in -// TerminatorOpTypes. -template -struct HasSomeTerminator { - static LogicalResult verifyTrait(Operation *op) { - for (auto ®ion : op->getRegions()) { - for (auto &block : region) { - if (!block.empty()) { - if (Operation *operation = &block.back(); - !llvm::isa_and_nonnull(operation)) - return operation->emitOpError("is not an allowed terminator") - .attachNote(op->getLoc()) - .append("in this context: "); - } - } - } - return success(); - } -}; - -// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) -// has valid BDs. -template -LogicalResult HasValidBDs::verifyTrait(Operation *op) { - auto element = cast(op); - const auto &targetModel = getTargetModel(op); - int bdMax = - targetModel.getNumBDs(element.getTileLoc().col, element.getTileLoc().row); - - int bdNum = 0; - for (auto &block : element.getBody()) { - if (!block.template getOps().empty()) { - if (bdNum >= bdMax) { - auto bd = *block.template getOps().begin(); - return (op->emitOpError("has more than ") << bdMax << " blocks") - .attachNote(bd.getLoc()) - .append("no space for this bd: "); - } - bdNum++; - } - } - return success(); -} - -// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp) -// has valid DMA channels. -template -LogicalResult HasValidDMAChannels::verifyTrait(Operation *op) { - auto element = cast(op); - DenseSet usedChannels; - for (auto &bodyOp : element.getBody().getOps()) { - // check for duplicate DMA channels within the same MemTileDMAOp - if (auto dmaStart = dyn_cast(bodyOp)) { - DMAChannel dmaChan = {dmaStart.getChannelDir(), - static_cast(dmaStart.getChannelIndex())}; - if (usedChannels.count(dmaChan)) - return dmaStart.emitOpError() - << "duplicate DMA channel " - << stringifyDMAChannelDir(dmaChan.direction) << dmaChan.channel - << " not allowed"; - usedChannels.insert(dmaChan); - } - } - return success(); -} - -//===----------------------------------------------------------------------===// -// ObjectFifoCreateOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoCreateOp::verify() { - if (isa(getElemNumber())) { - if (size_t numDepths = dyn_cast(getElemNumber()).size(); - numDepths != getConsumerTiles().size() + 1) // +1 for producer depth - return emitOpError( - "does not have enough depths specified for producer " - "and for each consumer."); - } - - if (getProducerTileOp().isShimTile() && !getDimensionsToStream().empty()) { - return emitError( - "`toStream` data layout transformations are not supported " - "on shim tile producers"); - } - - return success(); -} - -TileOp ObjectFifoCreateOp::getProducerTileOp() { - return cast(getProducerTile().getDefiningOp()); -} - -namespace xilinx::AIE { - -ParseResult parseObjectFifoProducerTile(OpAsmParser &parser, - OpAsmParser::UnresolvedOperand &operand, - BDDimLayoutArrayAttr &dimensions) { - std::vector emptyDims = {}; - if (parser.parseOperand(operand)) return failure(); - if (succeeded(parser.parseOptionalKeyword("toStream"))) { - if (parser.parseCustomAttributeWithFallback( - dimensions)) { - return failure(); - } - } else { - dimensions = - BDDimLayoutArrayAttr::get(parser.getContext(), ArrayRef(emptyDims)); - } - return success(); -} - -void printObjectFifoProducerTile(OpAsmPrinter &printer, Operation *op, - Value operand, - BDDimLayoutArrayAttr dimensions) { - printer << operand; - if (!dimensions.empty()) { - printer << " toStream "; - printer.printStrippedAttrOrType(dimensions); - } -} - -ParseResult parseObjectFifoConsumerTiles( - OpAsmParser &parser, SmallVectorImpl &tiles, - BDDimLayoutArrayArrayAttr &dimensions) { - // parseCommaSeparatedList doesn't handle the missing case for "none", - // so we handle it custom here. - std::vector tileDims = {}; - - auto parseOneOperand = [&]() -> ParseResult { - if (parser.parseOperand(tiles.emplace_back(), true)) { - return failure(); - } - // 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 - BDDimLayoutArrayAttr dimAttr = - BDDimLayoutArrayAttr::get(parser.getContext(), {}); - - if (succeeded(parser.parseOptionalKeyword("fromStream"))) { - // If specified, parse actual data layout transform dimensions - if (parser.parseCustomAttributeWithFallback( - dimAttr)) { - return failure(); - } - } - tileDims.emplace_back(dimAttr); - return success(); - }; - - if (parser.parseCommaSeparatedList(AsmParser::Delimiter::None, - parseOneOperand, " in operand list")) - return failure(); - - dimensions = BDDimLayoutArrayArrayAttr::get(parser.getContext(), tileDims); - return success(); -} - -void printObjectFifoConsumerTiles(OpAsmPrinter &printer, Operation *op, - OperandRange tiles, - BDDimLayoutArrayArrayAttr dimsPerTileAttr) { - size_t TileLocx = 0; - for (auto tile : tiles) { - printer << tile; - if (dimsPerTileAttr && TileLocx < dimsPerTileAttr.size() && - dimsPerTileAttr[TileLocx] && !dimsPerTileAttr[TileLocx].empty()) { - printer << " fromStream "; - printer.printStrippedAttrOrType(dimsPerTileAttr[TileLocx]); - } - if (TileLocx < tiles.size() - 1) { - printer << ", "; - } - TileLocx++; - } -} - -} // namespace xilinx::AIE - -//===----------------------------------------------------------------------===// -// ObjectFifoLinkOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoLinkOp::verify() { - if (isJoin() && isDistribute()) - return emitError( - "ObjectFifoLinkOp does not support 'join' and " - "'distribute' at the same time"); - - if (auto sharedTile = getOptionalSharedTile(); !sharedTile) - return emitError( - "ObjectFifoLinkOp must have a link point, i.e., a " - "shared tile between objectFifos"); - - if (isJoin()) { - ObjectFifoCreateOp fifoOut = getOutputObjectFifos()[0]; - auto elemType = - llvm::cast(fifoOut.getElemType()).getElementType(); - int64_t outputSize = 1; - for (auto dim : elemType.getShape()) outputSize *= dim; - - int inputSize = 0; - for (auto fifoIn : getInputObjectFifos()) { - auto elemType = - llvm::cast(fifoIn.getElemType()).getElementType(); - int64_t nextInputSize = 1; - for (int64_t dim : elemType.getShape()) nextInputSize *= dim; - inputSize += nextInputSize; - } - if (inputSize != outputSize) - return emitError( - "Total size of input objFifos in ObjectFifoLinkOp must " - "be equal to size of output objFifo"); - - } else if (isDistribute()) { - ObjectFifoCreateOp fifoIn = getInputObjectFifos()[0]; - if (!fifoIn.getDimensionsToStream().empty()) { - return emitOpError( - "currently does not support objectFifos with " - "dimensionsToStream."); - } - for (auto dims : fifoIn.getDimensionsFromStreamPerConsumer()) { - if (!dims.empty()) - return emitOpError( - "currently does not support objectFifos with " - "dimensionsFromStreamPerConsumer."); - } - - auto elemType = - llvm::cast(fifoIn.getElemType()).getElementType(); - int64_t inputSize = 1; - for (auto dim : elemType.getShape()) inputSize *= dim; - - int outputSize = 0; - for (auto fifoOut : getOutputObjectFifos()) { - for (auto dims : fifoOut.getDimensionsFromStreamPerConsumer()) { - if (!dims.empty()) - return emitOpError( - "currently does not support objectFifos with " - "dimensionsFromStreamPerConsumer."); - } - - auto elemType = - llvm::cast(fifoOut.getElemType()).getElementType(); - int64_t nextOutputSize = 1; - for (int64_t dim : elemType.getShape()) nextOutputSize *= dim; - outputSize += nextOutputSize; - } - if (outputSize != inputSize) - return emitError( - "Total size of output objFifos in ObjectFifoLinkOp must " - "be equal to size of input objFifo"); - } - - return success(); -} - -std::optional ObjectFifoLinkOp::getOptionalSharedTile() { - if (isJoin()) { - auto fifoOut = getOutputObjectFifos()[0]; - for (auto fifoIn : getInputObjectFifos()) - if (fifoOut.getProducerTile() != fifoIn.getConsumerTiles()[0]) return {}; - return {fifoOut.getProducerTile()}; - } - - if (isDistribute()) { - auto fifoIn = getInputObjectFifos()[0]; - for (auto fifoOut : getOutputObjectFifos()) - if (fifoIn.getConsumerTiles()[0] != fifoOut.getProducerTile()) return {}; - return {fifoIn.getConsumerTiles()[0]}; - } - - auto fifoIn = getInputObjectFifos(); - if (auto fifoOut = getOutputObjectFifos(); - !fifoIn.empty() && !fifoOut.empty()) - for (auto consumerIn : fifoIn[0].getConsumerTiles()) - if (consumerIn == fifoOut[0].getProducerTile()) - return {fifoOut[0].getProducerTile()}; - return {}; -} - -std::vector ObjectFifoLinkOp::getInputObjectFifos() { - std::vector inputObjFifos; - Operation *parent = getOperation(); - while ((parent = parent->getParentOp())) { - if (parent->hasTrait()) { - for (auto sym : getFifoIns()) { - auto name = dyn_cast(sym); - if (auto *st = SymbolTable::lookupSymbolIn(parent, name); - isa_and_nonnull(st)) - inputObjFifos.push_back(dyn_cast(st)); - } - } - } - return inputObjFifos; -} - -std::vector ObjectFifoLinkOp::getOutputObjectFifos() { - std::vector outputObjFifos; - Operation *parent = getOperation(); - while ((parent = parent->getParentOp())) { - if (parent->hasTrait()) { - for (auto sym : getFifoOuts()) { - auto name = dyn_cast(sym); - if (auto *st = SymbolTable::lookupSymbolIn(parent, name); - isa_and_nonnull(st)) - outputObjFifos.push_back(dyn_cast(st)); - } - } - } - return outputObjFifos; -} - -//===----------------------------------------------------------------------===// -// ObjectFifoRegisterExternalBuffersOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoRegisterExternalBuffersOp::verify() { - if (!getTileOp().isShimTile()) return emitOpError("tile is not a shim tile"); - - return success(); -} - -TileOp ObjectFifoRegisterExternalBuffersOp::getTileOp() { - return cast(getTile().getDefiningOp()); -} - -ObjectFifoCreateOp ObjectFifoRegisterExternalBuffersOp::getObjectFifo() { - Operation *parent = getOperation(); - while ((parent = parent->getParentOp())) { - if (parent->hasTrait()) { - if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); - isa_and_nonnull(st)) - return dyn_cast(st); - } - } - return {}; -} - -//===----------------------------------------------------------------------===// -// ObjectFifoAcquireOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoAcquireOp::verify() { - if (acqNumber() < 1) return emitOpError("must acquire at least one element"); - - auto parent = getOperation()->getParentOfType(); - if (parent == nullptr) - return emitOpError("must be called from inside a CoreOp"); - - auto coreTile = parent.getTile(); - auto objFifo = getObjectFifo(); - if (getPort() == ObjectFifoPort::Produce) { - if (coreTile != objFifo.getProducerTile()) - return parent.emitOpError( - "producer port of objectFifo accessed by core running " - "on non-producer tile"); - } else if (getPort() == ObjectFifoPort::Consume) { - bool found = false; - for (auto consumerTile : objFifo.getConsumerTiles()) { - if (coreTile == consumerTile) { - found = true; - break; - } - } - if (!found) - return parent.emitOpError( - "consumer port of objectFifo accessed by core running " - "on non-consumer tile"); - } - - auto objFifoElem = - llvm::cast(getObjectFifo().getElemType()) - .getElementType(); - auto objFifoSubviewElem = - llvm::cast(getResult().getType()) - .getElementType(); - if (objFifoElem != objFifoSubviewElem) - return emitOpError( - "ObjectFifo element and ObjectFifoSubview element must match.\n"); - - return success(); -} - -ObjectFifoCreateOp ObjectFifoAcquireOp::getObjectFifo() { - Operation *parent = getOperation(); - while ((parent = parent->getParentOp())) { - if (parent->hasTrait()) { - if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); - isa_and_nonnull(st)) - return dyn_cast(st); - } - } - return {}; -} - -//===----------------------------------------------------------------------===// -// ObjectFifoReleaseOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoReleaseOp::verify() { - if (relNumber() < 1) return emitOpError("must release at least one element"); - - auto parent = getOperation()->getParentOfType(); - if (parent == nullptr) - return emitOpError("must be called from inside a CoreOp"); - - auto coreTile = parent.getTile(); - auto objFifo = getObjectFifo(); - if (getPort() == ObjectFifoPort::Produce) { - if (coreTile != objFifo.getProducerTile()) - return parent.emitOpError( - "producer port of objectFifo accessed by core running " - "on non-producer tile"); - } else if (getPort() == ObjectFifoPort::Consume) { - bool found = false; - for (auto consumerTile : objFifo.getConsumerTiles()) { - if (coreTile == consumerTile) { - found = true; - break; - } - } - if (!found) - return parent.emitOpError( - "consumer port of objectFifo accessed by core running " - "on non-consumer tile"); - } - - return success(); -} - -ObjectFifoCreateOp ObjectFifoReleaseOp::getObjectFifo() { - Operation *parent = getOperation(); - while ((parent = parent->getParentOp())) { - if (parent->hasTrait()) { - if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); - isa_and_nonnull(st)) - return dyn_cast(st); - } - } - return {}; -} - -//===----------------------------------------------------------------------===// -// ObjectFifoSubviewAccessOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoSubviewAccessOp::verify() { - if (auto parent = getOperation()->getParentOfType(); - parent == nullptr) - return emitOpError("must be called from inside a CoreOp"); - - if (auto acqOp = getSubview().getDefiningOp(); - getIndex() >= acqOp.acqNumber()) - return emitOpError( - "accessed farther than number of acquired elements " - "(index out of bounds)."); - - return success(); -} - -//===----------------------------------------------------------------------===// -// ObjectFifoRegisterProcessOp -//===----------------------------------------------------------------------===// - -LogicalResult ObjectFifoRegisterProcessOp::verify() { - if (getProcessLength() < 1) return emitOpError("process length must be >= 1"); - - if (getAcquirePattern().size() != getReleasePattern().size()) { - // acquire pattern size = process length (i.e., release pattern will be - // duplicated by process length times) OR the other way around - if (getAcquirePattern().size() != getProcessLength() && - getProcessLength() != getReleasePattern().size()) - return emitOpError( - "Acquire and Release patterns must be of equal length, or " - "longest length of one must be equal to process " - "length of the other"); - } - - return success(); -} - -ObjectFifoCreateOp ObjectFifoRegisterProcessOp::getObjectFifo() { - Operation *parent = getOperation(); - while ((parent = parent->getParentOp())) { - if (parent->hasTrait()) { - if (auto *st = SymbolTable::lookupSymbolIn(parent, getObjFifoName()); - isa_and_nonnull(st)) - return dyn_cast(st); - } - } - return {}; -} - -//===----------------------------------------------------------------------===// -// CascadeFlowOp -//===----------------------------------------------------------------------===// - -LogicalResult CascadeFlowOp::verify() { - TileOp src = getSourceTileOp(); - TileOp dst = getDestTileOp(); - const auto &t = getTargetModel(src); - - if (src.isShimTile() || dst.isShimTile()) - return emitOpError("shimTile row has no cascade stream interface"); - if (t.isMemTile(src.colIndex(), src.rowIndex()) || - t.isMemTile(dst.colIndex(), dst.rowIndex())) - return emitOpError("memTile row has no cascade stream interface"); - - if (!t.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow()) && - !t.isWest(src.getCol(), src.getRow(), dst.getCol(), dst.getRow()) && - !t.isNorth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow()) && - !t.isEast(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { - return emitOpError("tiles must be adjacent"); - } - return success(); -} - -TileOp CascadeFlowOp::getSourceTileOp() { - return cast(getSourceTile().getDefiningOp()); -} - -TileOp CascadeFlowOp::getDestTileOp() { - return cast(getDestTile().getDefiningOp()); -} - -//===----------------------------------------------------------------------===// -// ConfigureCascadeOp -//===----------------------------------------------------------------------===// - -LogicalResult ConfigureCascadeOp::verify() { - const auto &t = getTargetModel(*this); - TileOp tile = cast(getTile().getDefiningOp()); - CascadeDir inputDir = getInputDir(); - CascadeDir outputDir = getOutputDir(); - - if (tile.isShimTile()) - return emitOpError("shimTile row has no cascade stream interface"); - if (t.isMemTile(tile.colIndex(), tile.rowIndex())) - return emitOpError("memTile row has no cascade stream interface"); - - if (t.getTargetArch() == AIEArch::AIE2) { - if (inputDir == CascadeDir::South || inputDir == CascadeDir::East) { - return emitOpError("input direction of cascade must be North or West on ") - << stringifyAIEArch(t.getTargetArch()); - } - if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { - return emitOpError( - "output direction of cascade must be South or East on ") - << stringifyAIEArch(t.getTargetArch()); - } - } else { - return emitOpError("cascade not supported in ") - << stringifyAIEArch(t.getTargetArch()); - } - return success(); -} - -//===----------------------------------------------------------------------===// -// PutCascadeOp -//===----------------------------------------------------------------------===// - -LogicalResult PutCascadeOp::verify() { - const auto &targetModel = getTargetModel(*this); - Type type = getCascadeValue().getType(); - DataLayout dataLayout = DataLayout::closest(*this); - auto bits = dataLayout.getTypeSizeInBits(type); - auto archbits = targetModel.getAccumulatorCascadeSize(); - if (bits != archbits) - return emitOpError("type must match architecture cascade width (") - << archbits << " bits in " - << stringifyAIEArch(targetModel.getTargetArch()) << ")"; - return success(); -} - -//===----------------------------------------------------------------------===// -// GetCascadeOp -//===----------------------------------------------------------------------===// - -LogicalResult GetCascadeOp::verify() { - const auto &targetModel = getTargetModel(*this); - Type type = getCascadeValue().getType(); - DataLayout dataLayout = DataLayout::closest(*this); - auto bits = dataLayout.getTypeSizeInBits(type); - if (targetModel.getTargetArch() == AIEArch::AIE1) { - if (bits != 384) return emitOpError("must be a 384-bit type"); - } else if (targetModel.getTargetArch() == AIEArch::AIE2) { - if (bits != 512) return emitOpError("must be a 512-bit type"); - } else - return emitOpError("cascade not supported in ") - << stringifyAIEArch(targetModel.getTargetArch()); - return success(); -} - -//===----------------------------------------------------------------------===// -// DeviceOp -//===----------------------------------------------------------------------===// - -const AIETargetModel &DeviceOp::getTargetModel() { - return xilinx::AIE::getTargetModel(getDevice()); -} - -LogicalResult DeviceOp::verify() { return success(); } - -//===----------------------------------------------------------------------===// -// TileOp -//===----------------------------------------------------------------------===// - -LogicalResult TileOp::verify() { - const auto &targetModel = getTargetModel(*this); - int columns = targetModel.columns(); - int rows = targetModel.rows(); - if (colIndex() >= columns) - return emitOpError("column index (") - << colIndex() - << ") must be less than the number of columns in the device (" - << columns << ")"; - if (rowIndex() >= rows) - return emitOpError("row index (") - << rowIndex() - << ") must be less than the number of rows in the device (" << rows - << ")"; - - auto users = getResult().getUsers(); - bool found = false; - for (auto *user : users) { - if (llvm::isa(*user)) { - if (found) return emitOpError("can only have one switchbox"); - found = true; - } - } - - return success(); -} - -size_t TileOp::getNumSourceConnections(WireBundle bundle) { - const auto &targetModel = getTargetModel(*this); - if (bundle == WireBundle::Core || bundle == WireBundle::DMA) - // Note dest is correct here, since direction is reversed. - { - // Note dest is correct here, since direction is reversed. - if (targetModel.isShimNOCTile(getCol(), getRow()) || - targetModel.isShimPLTile(getCol(), getRow())) - return targetModel.getNumDestShimMuxConnections(getCol(), getRow(), - bundle); - return targetModel.getNumDestSwitchboxConnections(getCol(), getRow(), - bundle); - } - return 0; -} - -size_t TileOp::getNumDestConnections(WireBundle bundle) { - const auto &targetModel = getTargetModel(*this); - if (bundle == WireBundle::Core || bundle == WireBundle::DMA) - // Note source is correct here, since direction is reversed. - { - // Note source is correct here, since direction is reversed. - if (targetModel.isShimNOCTile(getCol(), getRow()) || - targetModel.isShimPLTile(getCol(), getRow())) - return targetModel.getNumDestShimMuxConnections(getCol(), getRow(), - bundle); - return targetModel.getNumSourceSwitchboxConnections(getCol(), getRow(), - bundle); - } - return 0; -} - -bool TileOp::isMemTile() { - const auto &targetModel = getTargetModel(*this); - return targetModel.isMemTile(getCol(), getRow()); -} - -bool TileOp::isShimNOCTile() { - const auto &targetModel = getTargetModel(*this); - return targetModel.isShimNOCTile(getCol(), getRow()); -} - -bool TileOp::isShimPLTile() { - const auto &targetModel = getTargetModel(*this); - return targetModel.isShimPLTile(getCol(), getRow()); -} - -bool TileOp::isShimNOCorPLTile() { - const auto &targetModel = getTargetModel(*this); - return targetModel.isShimNOCorPLTile(getCol(), getRow()); -} - -bool isLegalTileConnection(TileOp tile, const AIETargetModel &targetModel, - MasterSetOp masterOp, PacketRulesOp slaveOp) { - auto srcBundle = slaveOp.sourcePort().bundle; - auto srcChan = slaveOp.sourcePort().channel; - auto dstBundle = masterOp.destPort().bundle; - auto dstChan = masterOp.destPort().channel; - return targetModel.isLegalTileConnection( - tile.colIndex(), tile.rowIndex(), srcBundle, srcChan, dstBundle, dstChan); -} - -bool isLegalTileConnection(TileOp tile, const AIETargetModel &targetModel, - ConnectOp connectOp) { - auto srcBundle = connectOp.getSourceBundle(); - auto srcChan = connectOp.getSourceChannel(); - auto dstBundle = connectOp.getDestBundle(); - auto dstChan = connectOp.getDestChannel(); - return targetModel.isLegalTileConnection( - tile.colIndex(), tile.rowIndex(), srcBundle, srcChan, dstBundle, dstChan); -} - -//===----------------------------------------------------------------------===// -// ShimSwitchboxOp -//===----------------------------------------------------------------------===// - -LogicalResult ShimSwitchboxOp::verify() { - Region &body = getConnections(); - DenseSet destset; - if (body.empty()) return emitOpError("should have non-empty body"); - - for (auto &ops : body.front()) { - if (auto connectOp = dyn_cast(ops)) { - Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; - if (destset.count(dest)) - return connectOp.emitOpError("targets same destination ") - << stringifyWireBundle(dest.bundle) << ": " << dest.channel - << " as another connect operation"; - destset.insert(dest); - } else if (isa(ops)) { - // continue; - } else { - return ops.emitOpError("cannot be contained in a Switchbox op"); - } - } - - return success(); -} - -//===----------------------------------------------------------------------===// -// ShimMuxOp -//===----------------------------------------------------------------------===// - -LogicalResult ShimMuxOp::verify() { - Region &body = getConnections(); - DenseSet destset; - if (body.empty()) return emitOpError("should have non-empty body"); - - for (auto &ops : body.front()) { - if (auto connectOp = dyn_cast(ops)) { - Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; - if (destset.count(dest)) - return connectOp.emitOpError("targets same destination ") - << stringifyWireBundle(dest.bundle) << ": " << dest.channel - << " as another connect operation"; - destset.insert(dest); - } else if (isa(ops)) { - // continue; - } else { - return ops.emitOpError("cannot be contained in a Switchbox op"); - } - } - return success(); -} - -size_t ShimMuxOp::getNumSourceConnections(WireBundle bundle) { - auto tile = getTileOp(); - const auto &targetModel = getTargetModel(*this); - return targetModel.getNumSourceShimMuxConnections(tile.getCol(), - tile.getRow(), bundle); -} - -size_t ShimMuxOp::getNumDestConnections(WireBundle bundle) { - auto tile = getTileOp(); - const auto &targetModel = getTargetModel(*this); - return targetModel.getNumDestShimMuxConnections(tile.getCol(), tile.getRow(), - bundle); -} - -TileOp ShimMuxOp::getTileOp() { - return cast(getTile().getDefiningOp()); -} - -int ShimMuxOp::colIndex() { return getTileOp().colIndex(); } - -int ShimMuxOp::rowIndex() { return getTileOp().rowIndex(); } - -//===----------------------------------------------------------------------===// -// ShimDMAOp -//===----------------------------------------------------------------------===// - -LogicalResult ShimDMAOp::verify() { - Region &body = getBody(); - DenseSet usedChannels; - std::vector inputChannels; - std::vector outputChannels; - - if (getBody().empty()) return emitOpError("should have non-empty body"); - - if (!getTileOp().isShimNOCTile()) - return emitOpError("must be in a ShimTile with a NOC connection"); - - if (HasSomeTerminator::verifyTrait(*this) - .failed()) - return failure(); - - for (auto &bodyOp : body.getOps()) { - // check for duplicate DMA channels within the same ShimDMAOp - if (auto dmaStart = dyn_cast(bodyOp)) { - DMAChannel dmaChan = {dmaStart.getChannelDir(), - static_cast(dmaStart.getChannelIndex())}; - if (usedChannels.count(dmaChan)) - return dmaStart.emitOpError() - << "duplicate DMA channel " - << stringifyDMAChannelDir(dmaChan.direction) << dmaChan.channel - << " in MemOp"; - usedChannels.insert(dmaChan); - // check if number of input and output channels is more than available - // hardware - if (dmaChan.direction == DMAChannelDir::S2MM) - inputChannels.push_back(dmaChan); - else - outputChannels.push_back(dmaChan); - } - } - - if (inputChannels.size() > - getTileOp().getNumSourceConnections(WireBundle::DMA)) - return emitOpError("uses more input channels than available on this tile"); - - if (outputChannels.size() > - getTileOp().getNumDestConnections(WireBundle::DMA)) - return emitOpError("uses more output channels than available on this tile"); - - return success(); -} - -TileOp ShimDMAOp::getTileOp() { - return cast(getTile().getDefiningOp()); -} - -int ShimDMAOp::colIndex() { return getTileOp().colIndex(); } - -int ShimDMAOp::rowIndex() { return getTileOp().rowIndex(); } - -LogicalResult PacketRulesOp::verify() { - if (Region &body = getRules(); body.empty()) - return emitOpError("should have non-empty body"); - return success(); -} - -LogicalResult PacketFlowOp::verify() { - Region &body = getPorts(); - if (body.empty()) return emitOpError("should have non-empty body"); - - for (auto &ops : body.front()) { - if (!isa(ops)) - return ops.emitOpError("cannot be contained in a PacketFlow op"); - } - - return success(); -} - -//===----------------------------------------------------------------------===// -// CoreOp -//===----------------------------------------------------------------------===// - -LogicalResult CoreOp::verify() { - if (getBody().empty()) return emitOpError("should have non-empty body"); - if (getTileOp().isShimTile()) - return emitOpError("CoreOp cannot be created on shim tile, i.e. row == 0"); - if (getTileOp().isMemTile()) - return emitOpError("CoreOp cannot be created on mem tile"); - return success(); -} - -int CoreOp::colIndex() { return getTileOp().colIndex(); } - -int CoreOp::rowIndex() { return getTileOp().rowIndex(); } - -TileOp CoreOp::getTileOp() { return cast(getTile().getDefiningOp()); } - -//===----------------------------------------------------------------------===// -// BufferOp -//===----------------------------------------------------------------------===// - -int64_t BufferOp::getAllocationSize() { - auto type = llvm::cast(getType()); - return type.getNumElements() * type.getElementTypeBitWidth() / 8; -} - -TileOp BufferOp::getTileOp() { return cast(getTile().getDefiningOp()); } - -LogicalResult BufferOp::verify() { - if (UsesAreAccessable::verifyTrait(*this).failed()) return failure(); - return success(); -} - -// FIXME: make address assignment for buffers explicit and move this function to -// an interface -int32_t xilinx::AIE::getBufferBaseAddress(Operation *bufOp) { - if (auto buf = dyn_cast(bufOp)) { - assert(buf.getAddress().has_value() && "buffer must have address assigned"); - return buf.getAddress().value(); - } - if (isa_and_nonnull(bufOp)) - llvm::report_fatal_error( - "External buffer addresses are assigned at runtime."); - llvm::report_fatal_error("unknown buffer type"); -} - -void xilinx::AIE::collectTiles(DeviceOp &device, - DenseMap &tiles) { - for (auto tile : device.getOps()) { - int colIndex = tile.colIndex(); - int rowIndex = tile.rowIndex(); - tiles[{colIndex, rowIndex}] = tile; - } -} - -void xilinx::AIE::collectBuffers( - DeviceOp &device, - DenseMap> &buffers) { - for (BufferOp buffer : device.getOps()) { - Operation *tileOp = buffer.getTile().getDefiningOp(); - buffers[tileOp].push_back(buffer); - } -} - -static void printBufferInitialValue(OpAsmPrinter &p, BufferOp op, Type type, - Attribute initialValue) { - if (op.getInitialValue()) { - p << "= "; - p.printAttributeWithoutType(initialValue); - } -} - -static ParseResult parseBufferInitialValue(OpAsmParser &parser, Type &type, - Attribute &initialValue) { - auto memrefType = llvm::cast(type); - if (!memrefType.hasStaticShape()) - return parser.emitError(parser.getNameLoc()) - << "type should be static shaped memref, but got " << type; - - if (parser.parseOptionalEqual()) return success(); - - Type tensorType = mlir::memref::getTensorTypeFromMemRefType(memrefType); - if (parser.parseAttribute(initialValue, tensorType)) return failure(); - if (!llvm::isa(initialValue)) - return parser.emitError(parser.getNameLoc()) - << "initial value should be an elements attribute"; - return success(); -} - -//===----------------------------------------------------------------------===// -// MemOp -//===----------------------------------------------------------------------===// - -LogicalResult MemOp::verify() { - Region &body = getBody(); - DenseSet usedChannels; - std::vector inputChannels; - std::vector outputChannels; - if (body.empty()) return emitOpError("should have non-empty body"); - - if (HasSomeTerminator::verifyTrait(*this) - .failed()) - return failure(); - - for (auto &bodyOp : body.getOps()) { - // check for duplicate DMA channels within the same MemOp - if (auto dmaStart = dyn_cast(bodyOp)) { - DMAChannel dmaChan = {dmaStart.getChannelDir(), - static_cast(dmaStart.getChannelIndex())}; - if (usedChannels.count(dmaChan)) - return dmaStart.emitOpError() - << "duplicate DMA channel " - << stringifyDMAChannelDir(dmaChan.direction) << dmaChan.channel - << " in MemOp"; - usedChannels.insert(dmaChan); - // check if number of input and output channels is more than available - // hardware - if (dmaChan.direction == DMAChannelDir::S2MM) - inputChannels.push_back(dmaChan); - else - outputChannels.push_back(dmaChan); - } - - if (auto allocOp = dyn_cast(bodyOp)) - if (!allocOp->getAttr("id")) - return allocOp.emitOpError() - << "allocOp in MemOp region should have an id attribute"; - } - - if (inputChannels.size() > - getTileOp().getNumSourceConnections(WireBundle::DMA)) - return emitOpError("uses more input channels than available on this tile"); - - if (outputChannels.size() > - getTileOp().getNumDestConnections(WireBundle::DMA)) - return emitOpError("uses more output channels than available on this tile"); - - return success(); -} - -TileOp MemOp::getTileOp() { return cast(getTile().getDefiningOp()); } - -int MemOp::colIndex() { return getTileOp().colIndex(); } - -int MemOp::rowIndex() { return getTileOp().rowIndex(); } - -/// Returns the region on the current operation that is callable. This may -/// return nullptr in the case of an external callable object, e.g. an external -/// function. -Region *MemOp::getCallableRegion() { return &getBody(); } - -//===----------------------------------------------------------------------===// -// MemTileDMAOp -//===----------------------------------------------------------------------===// - -LogicalResult MemTileDMAOp::verify() { - std::vector inputChannels; - std::vector outputChannels; - - assert(getOperation()->getNumRegions() == 1 && - "MemTileDMAOp has zero region!"); - assert(!getBody().empty() && "MemTileDMAOp should have non-empty body"); - - if (HasSomeTerminator::verifyTrait(*this) - .failed()) - return failure(); - - for (auto &bodyOp : getBody().getOps()) { - if (auto allocOp = dyn_cast(bodyOp)) { - if (!allocOp->getAttr("id")) - return allocOp.emitOpError() - << "allocOp in MemTileDMAOp region should have an id attribute"; - } - if (auto startOp = dyn_cast(bodyOp)) { - // check if number of input and output channels is more than available - // hardware - DMAChannel dmaChan = {startOp.getChannelDir(), - static_cast(startOp.getChannelIndex())}; - if (dmaChan.direction == DMAChannelDir::S2MM) - inputChannels.push_back(dmaChan); - else - outputChannels.push_back(dmaChan); - - if (startOp.getChannelIndex() > 3) { - // Channels 4 and 5 in a memtile are restricted to only access local - // buffers and locks. - - // TODO: Move this code to the dialect - // Set of blocks found to be reachable within a given region. - llvm::SmallSet reachable; - SmallVector worklist; - Block *firstBD = startOp.getSuccessor(0); - reachable.insert(firstBD); - worklist.push_back(firstBD); - while (!worklist.empty()) { - Block *block = worklist.pop_back_val(); - if (block->empty()) continue; - auto successors = block->getTerminator()->getSuccessors(); - for (auto *i : successors) { - if (!reachable.contains(i)) { - reachable.insert(i); - worklist.push_back(i); - } - } - } - for (Block *b : reachable) { - for (DMABDOp bd : b->getOps()) { - if (auto bufferOp = bd.getBufferOp(); - bufferOp.getTileOp().colIndex() != colIndex() || - bufferOp.getTileOp().rowIndex() != rowIndex()) { - InFlightDiagnostic err = - bd.emitOpError() - << "is reachable from DMA channel " - << startOp.getChannelIndex() - << " and attempts to access a non-local buffer\n"; - err.attachNote(startOp->getLoc()) << "channel"; - err.attachNote(bufferOp->getLoc()) << "buffer"; - return err; - } - } - for (auto useLock : b->getOps()) { - if (auto lockOp = useLock.getLockOp(); - lockOp.getTileOp().colIndex() != colIndex() || - lockOp.getTileOp().rowIndex() != rowIndex()) { - InFlightDiagnostic err = - useLock.emitOpError() - << "is reachable from DMA channel " - << startOp.getChannelIndex() - << " and attempts to access a non-local lock\n"; - err.attachNote(startOp->getLoc()) << "channel"; - err.attachNote(lockOp->getLoc()) << "lock"; - return err; - } - } - } - } - } - } - - if (inputChannels.size() > - getTileOp().getNumSourceConnections(WireBundle::DMA)) - return emitOpError("uses more input channels than available on this tile"); - - if (outputChannels.size() > - getTileOp().getNumDestConnections(WireBundle::DMA)) - return emitOpError("uses more output channels than available on this tile"); - - return success(); -} - -//===----------------------------------------------------------------------===// -// DMAOp -//===----------------------------------------------------------------------===// - -LogicalResult DMAOp::verify() { - auto *parentOp = getOperation()->getParentOp(); - if (parentOp->getRegion(0).getBlocks().size() > 1) - return emitOpError("DMAOp can only appear in single block region"); - if (!parentOp->getRegion(0).getOps().empty()) - return emitOpError("DMAOp is not compatible with DMAStart ops"); - auto bdRegions = getBds(); - for (auto &bdRegion : bdRegions) { - if (!bdRegion.hasOneBlock()) - return emitOpError("DMAOp regions must have only one block"); - auto bds = llvm::to_vector_of(bdRegion.front().getOps()); - if (bds.size() != 1) - return emitOpError("DMAOp regions/blocks must have exactly one DMABDOp"); - auto useLocks = - llvm::to_vector_of(bdRegion.front().getOps()); - if (useLocks.size() != 2) - return emitOpError( - "DMAOp regions/blocks must have exactly two UseLock ops"); - } - return success(); -} - -//===----------------------------------------------------------------------===// -// DMABDOp -//===----------------------------------------------------------------------===// - -BufferOp DMABDOp::getBufferOp() { - return cast(getBuffer().getDefiningOp()); -} - -LogicalResult DMABDOp::verify() { - if (!isa(getBuffer().getDefiningOp())) - return emitOpError( - "BDs only support BufferOp or ExternalBufferOp operands."); - - if (getLenInBytes() % 4) - return emitOpError( - "transfer length must be multiple of 4 (i.e., represent " - "4 byte aligned address)"); - - TileLoc parentTileLoc = getParentTileElement(getOperation()).getTileLoc(); - - if (getOperation()->getParentOfType() && - (getBufferOp().getTileOp().colIndex() != parentTileLoc.col || - getBufferOp().getTileOp().rowIndex() != parentTileLoc.row)) - return emitOpError( - "Core tile DMAs can only access a buffer in the same tile."); - - const AIETargetModel &targetModel = getTargetModel(getOperation()); - - uint32_t maxBds = targetModel.getNumBDs(parentTileLoc.col, parentTileLoc.row); - if (std::optional bdId = getBdId(); - bdId.has_value() && static_cast(*bdId) >= maxBds) - return emitOpError("bdId attribute exceeds max: ") << maxBds - 1; - if (std::optional nextBdId = getNextBdId(); - nextBdId.has_value() && static_cast(*nextBdId) >= maxBds) - return emitOpError("nextBdId attribute exceeds max: ") << maxBds - 1; - if (auto dims = getDimensions(); dims.has_value()) { - size_t maxNDims = 3; - if (isa_and_nonnull(getOperation()->getParentOp())) - maxNDims = 4; - if (dims->size() > maxNDims) - return emitOpError() << "Cannot give more than " - << std::to_string(maxNDims) - << " dimensions for step sizes and wraps in this " - " tile (got " - << std::to_string(dims->size()) << " dimensions)."; - - MemRefType buffer = getBuffer().getType(); - int64_t maxIdx = 0; - for (BDDimLayoutAttr dim : *dims) { - maxIdx += dim.getStride() * (dim.getSize() - 1); - if (0 == dim.getStride()) - return emitOpError() - << "Invalid step size; must be a positive integer."; - if (dim.getStride() > buffer.getNumElements()) - return emitOpError() - << "Step size " << std::to_string(dim.getStride()) << " " - << "exceeds memref size " - << std::to_string(buffer.getNumElements()); - if (dim.getSize() >= (1UL << 9) + 1) - return emitOpError() << "Size may not exceed 1023."; - if (dim.getStride() >= (1UL << 19)) - return emitOpError() << "Stride may not exceed " << (1 << 20); - } - - if (buffer.getNumElements() <= maxIdx) - return emitOpError() << "Specified stride(s) and size(s) result in out " - "of bounds access in buffer, for index " - << std::to_string(maxIdx) << " in memref of length " - << std::to_string(buffer.getNumElements()) << "."; - - // Since streams read 32b words, there's no way to read eg 16b with stride - // of 2 (ie lower halfs of each 32b). So force it to be 1 (and then in - // CDODirect/XAIEV2 scale the size by 4/getBufferElementTypeWidthInBytes). - if (getBufferElementTypeWidthInBytes() < 4 && dims->back().getStride() != 1) - return emitOpError( - "For <32b width datatypes, inner-most dim stride must be 1"); - } - if (auto paddims = getPadDimensions(); paddims.has_value()) { - auto dims = getDimensions(); - if (!dims.has_value()) - return emitOpError() << "Padding requires n-d data layouts expressed as" - << " wrap(s) and stride(s)."; - if (dims->size() != paddims->size()) - return emitOpError() << "Mismatch number of dimensions between padding(s)" - << " and wrap(s) and stride(s)."; - if (!targetModel.isMemTile(parentTileLoc.col, parentTileLoc.row)) - return emitOpError() << "Padding is only supported by memtile dma bds."; - int actuallen = 1; - for (unsigned i = 0; i < paddims->size(); i++) { - auto dim = (*dims)[i]; - auto paddim = (*paddims)[i]; - actuallen *= paddim.getConstPadBefore() + paddim.getConstPadAfter() + - dim.getSize(); - if (actuallen > getLen()) - return emitOpError() << "Data exceeds len after padding."; - } - if ((paddims->back().getConstPadBefore() * - getBufferElementTypeWidthInBytes()) % - 4) - return emitOpError() << "Inner-most padding-before count must result in" - << " padding in 32-bit words."; - if ((paddims->back().getConstPadAfter() * - getBufferElementTypeWidthInBytes()) % - 4) - return emitOpError() << "Inner-most padding-after count must result in" - << " padding in 32-bit words."; - } - if (targetModel.isMemTile(parentTileLoc.col, parentTileLoc.row) || - targetModel.isCoreTile(parentTileLoc.col, parentTileLoc.row)) { - if (auto baseAddr = getBufferOp().getAddress(); baseAddr.has_value()) { - int offsetInBytes = *baseAddr + getOffsetInBytes(); - if (offsetInBytes % 4) - return emitOpError( - "bd address must be 4 byte (32b) aligned; got base+offset: ") - << offsetInBytes << " (bytes)"; - } - } - - if (!getLen() && !getBuffer().getType().hasStaticShape()) - return emitOpError() << "buffer with dynamic shape requires static length."; - - return success(); -} - -TileOp MemTileDMAOp::getTileOp() { - return cast(getTile().getDefiningOp()); -} - -int MemTileDMAOp::colIndex() { return getTileOp().colIndex(); } - -int MemTileDMAOp::rowIndex() { return getTileOp().rowIndex(); } - -/// Returns the region on the current operation that is callable. This may -/// return nullptr in the case of an external callable object, e.g. an external -/// function. -Region *MemTileDMAOp::getCallableRegion() { return &getBody(); } - -//===----------------------------------------------------------------------===// -// SwitchboxOp -//===----------------------------------------------------------------------===// - -LogicalResult SwitchboxOp::verify() { - Region &body = getConnections(); - DenseSet sourceset; - DenseSet destset; - auto tile = getTileOp(); - const auto &targetModel = getTargetModel(tile); - if (body.empty()) return emitOpError("should have non-empty body"); - for (auto &ops : body.front()) { - // Would be simpler if this could be templatized. - auto checkBound = [&ops](StringRef dir, WireBundle bundle, int index, - int bound) -> LogicalResult { - if (index >= bound) { - if (bound > 0) - return ops.emitOpError("index ") - << index << " for " << dir << " bundle " - << stringifyWireBundle(bundle) << " must be less than " - << bound; - return ops.emitOpError() - << dir << " bundle " << stringifyWireBundle(bundle) - << " not supported; index: " << index << ", bound: " << bound; - } - return success(); - }; - - if (auto connectOp = dyn_cast(ops)) { - Port source = {connectOp.getSourceBundle(), connectOp.sourceIndex()}; - sourceset.insert(source); - - Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; - if (destset.count(dest)) { - return connectOp.emitOpError() - << "; connecting " << to_string(source) << " to " - << to_string(dest) << " on " - << to_string(this->getTileOp().getTileLoc()) - << " targets same dst as another connect op; existing " - "destinations: " - << llvm::join(llvm::map_range( - destset, [](auto &p) { return to_string(p); }), - ", "); - } - destset.insert(dest); - - if (connectOp.sourceIndex() < 0) - return connectOp.emitOpError("source index cannot be less than zero"); - - if (checkBound("source", connectOp.getSourceBundle(), - connectOp.sourceIndex(), - getNumSourceConnections(connectOp.getSourceBundle())) - .failed()) - return failure(); - - if (connectOp.destIndex() < 0) - return connectOp.emitOpError("dest index cannot be less than zero"); - - if (checkBound("dest", connectOp.getDestBundle(), connectOp.destIndex(), - getNumDestConnections(connectOp.getDestBundle())) - .failed()) - return failure(); - - // Stream switch connection constraints - if (!isLegalTileConnection(tile, targetModel, connectOp)) - return connectOp.emitOpError("illegal stream switch connection"); - - } else if (auto connectOp = dyn_cast(ops)) { - Port dest = {connectOp.getDestBundle(), connectOp.destIndex()}; - if (destset.count(dest)) - return connectOp.emitOpError("targets same destination ") - << stringifyWireBundle(dest.bundle) << ": " << dest.channel - << " as another connect or masterset operation"; - destset.insert(dest); - - if (connectOp.destIndex() < 0) - return connectOp.emitOpError("dest index cannot be less than zero"); - - if (checkBound("dest", connectOp.getDestBundle(), connectOp.destIndex(), - getNumDestConnections(connectOp.getDestBundle())) - .failed()) - return failure(); - - int arbiter = -1; - for (auto val : connectOp.getAmsels()) { - auto amsel = dyn_cast(val.getDefiningOp()); - if (arbiter != -1 && arbiter != amsel.arbiterIndex()) - return connectOp.emitOpError( - "a master port can only be tied to one arbiter"); - arbiter = amsel.arbiterIndex(); - } - } else if (auto connectOp = dyn_cast(ops)) { - Port source = {connectOp.getSourceBundle(), connectOp.sourceIndex()}; - if (sourceset.count(source)) - return connectOp.emitOpError("packet switched source ") - << stringifyWireBundle(source.bundle) << source.channel - << " cannot match another connect or masterset operation"; - sourceset.insert(source); - - } else if (auto amselOp = dyn_cast(ops)) { - std::vector mstrs; - std::vector slvs; - for (auto *user : amselOp.getResult().getUsers()) { - if (auto s = dyn_cast(user)) { - auto pktRules = dyn_cast(s->getParentOp()); - slvs.push_back(pktRules); - } else if (auto m = dyn_cast(user)) - mstrs.push_back(m); - } - for (auto m : mstrs) { - for (auto s : slvs) { - // Stream switch connection constraints - if (!isLegalTileConnection(tile, targetModel, m, s)) { - return amselOp->emitOpError("illegal stream switch connection"); - } - } - } - } else if (isa(ops)) { - // continue; - } else { - return ops.emitOpError("cannot be contained in a Switchbox op"); - } - } - - return success(); -} - -TileOp SwitchboxOp::getTileOp() { - return cast(getTile().getDefiningOp()); -} - -int SwitchboxOp::colIndex() { return getTileOp().colIndex(); } - -int SwitchboxOp::rowIndex() { return getTileOp().rowIndex(); } - -template -struct HasSomeParent { - static LogicalResult verifyTrait(Operation *op) { - Operation *operation = op->getParentOp(); - while (operation) { - if (llvm::isa_and_nonnull(operation)) return success(); - operation = operation->getParentOp(); - } - return failure(); - } -}; - -TileOp LockOp::getTileOp() { return cast(getTile().getDefiningOp()); } - -int LockOp::colIndex() { return getTileOp().colIndex(); } - -int LockOp::rowIndex() { return getTileOp().rowIndex(); } - -LogicalResult LockOp::verify() { - if (auto result = UsesAreAccessable::verifyTrait(*this); result.failed()) - return result; - - if (getLockID().has_value()) { - const auto &targetModel = getTargetModel(getTileOp()); - auto tileOp = getTileOp(); - if (int numLocks = - targetModel.getNumLocks(tileOp.getCol(), tileOp.getRow()); - getLockID().value() >= numLocks) - return emitOpError("lock assigned invalid id (maximum is ") - << numLocks - 1 << ")"; - } - - return success(); -} - -struct UsesOneLockInDMABlock { - static LogicalResult verifyTrait(Operation *op) { - auto *block = op->getBlock(); - int lockID = -1; - for (auto op : block->getOps()) { - if (auto lock = dyn_cast(op.getLock().getDefiningOp()); - lock.getLockID().has_value()) { - if (lockID != -1 && lockID != lock.getLockIDValue()) return failure(); - lockID = lock.getLockIDValue(); - } - } - return success(); - } -}; - -struct AcquireReleaseOneStateInDMABlock { - static LogicalResult verifyTrait(Operation *op) { - auto *block = op->getBlock(); - int acqValue = -1, relValue = -1; - for (auto op : block->getOps()) { - if (op.acquire() || op.acquireGE()) { - if (acqValue != -1 && acqValue != op.getLockValue()) { - return failure(); - } - acqValue = op.getLockValue(); - } else if (op.release()) { - if (relValue != -1 && relValue != op.getLockValue()) { - return failure(); - } - relValue = op.getLockValue(); - } - } - return success(); - } -}; - -struct AccessesLocalLocks { - static LogicalResult verifyTrait(Operation *op) { - if (auto memOp = op->getParentOfType()) { - auto useLock = dyn_cast(op); - if (auto lock = useLock.getLockOp(); - lock.getTileOp().colIndex() != memOp.colIndex() || - lock.getTileOp().rowIndex() != memOp.rowIndex()) - return failure(); - } - return success(); - } -}; - -LogicalResult UseLockOp::verify() { - // AIE.useLock cannot be used at the top level - if (llvm::isa_and_nonnull((*this)->getParentOp())) - return (*this)->emitOpError("must be used in a core or memory operation."); - - const auto &targetModel = getTargetModel(*this); - if (targetModel.getTargetArch() == AIEArch::AIE1 && acquireGE()) - return (*this)->emitOpError( - "AcquireGreaterEqual is not supported in AIE1."); - - // Otherwise, AIE.useLock should be inside MemOp, MemTileDMAOp, or ShimDMAOp, - if (HasSomeParent::verifyTrait(*this) - .succeeded()) { - if (!(*this)->getBlock()) return (*this)->emitOpError("is not in a block."); - - if (targetModel.getTargetArch() == AIEArch::AIE1 && - UsesOneLockInDMABlock::verifyTrait(*this).failed()) - return (*this)->emitOpError( - "used in a DMA block that have multiple locks."); - - if (AcquireReleaseOneStateInDMABlock::verifyTrait(*this).failed()) - return (*this)->emitOpError( - "acquires/releases the lock in a DMA block from/to multiple states."); - - if (HasSomeParent::verifyTrait(*this).succeeded() && - AccessesLocalLocks::verifyTrait(*this).failed()) - return (*this)->emitOpError("can only access a lock in the same tile"); - return success(); - - // Or it can be in a CoreOp, or some FuncOp called from a CoreOp - } - if (HasSomeParent::verifyTrait(*this).succeeded()) { - return success(); - } - return (*this)->emitOpError() - << "expects some parent op to be one of " - << "AIE::device, AIE::core, func::func, AIE::mem, or AIE::shimDMA"; -} - #include "aie/AIEEnums.cpp.inc" #include "aie/AIEInterfaces.cpp.inc" #define GET_OP_CLASSES #include "aie/AIEOps.cpp.inc" -namespace xilinx::AIE { - -size_t SwitchboxOp::getNumSourceConnections(WireBundle bundle) { - auto tile = getTileOp(); - const auto &targetModel = getTargetModel(*this); - return targetModel.getNumSourceSwitchboxConnections(tile.getCol(), - tile.getRow(), bundle); -} - -size_t SwitchboxOp::getNumDestConnections(WireBundle bundle) { - auto tile = getTileOp(); - const auto &targetModel = getTargetModel(*this); - return targetModel.getNumDestSwitchboxConnections(tile.getCol(), - tile.getRow(), bundle); -} - -WireBundle getConnectingBundle(WireBundle dir) { - switch (dir) { - case WireBundle::North: - return WireBundle::South; - case WireBundle::South: - return WireBundle::North; - case WireBundle::East: - return WireBundle::West; - case WireBundle::West: - return WireBundle::East; - default: - return dir; - } -} - -} // namespace xilinx::AIE - // Include implementations for custom attributes #define GET_ATTRDEF_CLASSES #include "aie/AIEAttrs.cpp.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td deleted file mode 100644 index aa2dc5388..000000000 --- a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td +++ /dev/null @@ -1,41 +0,0 @@ -//===- AIETypes.td -----------------------------------------*- tablegen -*-===// -// -// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// - -#ifndef AIE_TYPES -#define AIE_TYPES - -include "AIE.td" -include "AIEAttrs.td" - -include "mlir/IR/AttrTypeBase.td" - -def AIE_ObjectFifoType : - DialectType($_self)">, - "AIE objectFifo type">; - -def AIE_ObjectFifoSubviewType : - DialectType($_self)">, - "AIE ObjectFifoSubview type">; - -def AIE_Type : AnyTypeOf<[AIE_ObjectFifoType, AIE_ObjectFifoSubviewType]>; - -def AIE_ObjectFifo_Depth : AnyAttrOf<[ConfinedAttr]>, ArrayAttr]>; - -def AnyScalarOrTensor : TypeConstraint, - "scalar-or-tensor">; - -def AnyScalar : TypeConstraint, - "scalar">; - -#endif // AIE_TYPES \ No newline at end of file From 8675a6a23336876b69a3002b65951b27f1f97a63 Mon Sep 17 00:00:00 2001 From: max Date: Sun, 4 Aug 2024 10:33:04 -0500 Subject: [PATCH 05/12] remove types --- .../plugins/target/AMD-AIE/aie/AIEDialect.h | 311 +----------------- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 9 +- .../plugins/target/AMD-AIE/aie/CMakeLists.txt | 11 - 3 files changed, 8 insertions(+), 323 deletions(-) diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index a8254f17b..ff5e6337a 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -43,16 +43,6 @@ mlir::StringAttr name(T &op) { } class TileOp; -template -inline TileOp getTileOp(T op) { - return cast(op.getTile().getDefiningOp()); -} - -} // namespace xilinx::AIE - -namespace xilinx::AIE { -mlir::LogicalResult verifyOffsetSizeAndStrideOp( - mlir::OffsetSizeAndStrideOpInterface op); } // namespace xilinx::AIE /// Include the generated interface declarations. @@ -80,312 +70,19 @@ struct MyOffsetSizeAndStrideOpInterface // Include dialect declarations such as parseAttributes, parseType #include "aie/AIEDialect.h.inc" -namespace xilinx::AIE { - -void registerAIETranslations(); - -} // namespace xilinx::AIE - -//////////////////////////////////////////////////////////////////////////////// -/////////////////////// Custom Types for the Dialect /////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -namespace xilinx::AIE { -namespace detail { -struct AIEObjectFifoTypeStorage; -} - -/// This class defines the AIE ObjectFifo type. -class AIEObjectFifoType - : public mlir::Type::TypeBase { - public: - /// Inherit some necessary constructors from 'TypeBase'. - using Base::Base; - - /// Create an instance of a `ObjectFifoType` with the given element type. - static AIEObjectFifoType get(mlir::MemRefType elementType); - - /// This method is used to verify the construction invariants. - static mlir::LogicalResult verify( - llvm::function_ref emitError, - mlir::MemRefType elementType); - - static constexpr llvm::StringLiteral name = "objectfifo"; - /// Returns the element type of this ObjectFifoType. - mlir::MemRefType getElementType(); -}; - -namespace detail { -struct AIEObjectFifoSubviewTypeStorage; -} - -/// This class defines the AIE ObjectFifoSubview type. -class AIEObjectFifoSubviewType - : public mlir::Type::TypeBase { - public: - /// Inherit some necessary constructors from 'TypeBase'. - using Base::Base; - - /// Create an instance of a `SubviewType` with the given element type. - static AIEObjectFifoSubviewType get(mlir::MemRefType elementType); - - /// This method is used to verify the construction invariants. - static mlir::LogicalResult verify( - llvm::function_ref emitError, - mlir::MemRefType elementType); - - static constexpr llvm::StringLiteral name = "objectfifosubview"; - /// Returns the element type of this SubviewType. - mlir::MemRefType getElementType(); -}; - -} // namespace xilinx::AIE - -//////////////////////////////////////////////////////////////////////////////// -// Custom Attributes /////////////////////////////////////////////////////////// -//////////////////////////////////////////////////////////////////////////////// - #define GET_ATTRDEF_CLASSES #include "aie/AIEAttrs.h.inc" -//////////////////////////////////////////////////////////////////////////////// -//////////////////// Custom Operations for the Dialect ///////////////////////// -//////////////////////////////////////////////////////////////////////////////// - -namespace xilinx::AIE { - -WireBundle getConnectingBundle(WireBundle dir); - -#define GENERATE_TO_STRING(TYPE_WITH_INSERTION_OP) \ - friend std::string to_string(const TYPE_WITH_INSERTION_OP &s) { \ - std::ostringstream ss; \ - ss << s; \ - return ss.str(); \ - } - -typedef struct Port { - WireBundle bundle; - int channel; - - bool operator==(const Port &rhs) const { - return std::tie(bundle, channel) == std::tie(rhs.bundle, rhs.channel); - } - - bool operator!=(const Port &rhs) const { return !(*this == rhs); } - - bool operator<(const Port &rhs) const { - return std::tie(bundle, channel) < std::tie(rhs.bundle, rhs.channel); - } - - friend std::ostream &operator<<(std::ostream &os, const Port &port) { - os << "("; - switch (port.bundle) { - case WireBundle::Core: - os << "Core"; - break; - case WireBundle::DMA: - os << "DMA"; - break; - case WireBundle::North: - os << "N"; - break; - case WireBundle::East: - os << "E"; - break; - case WireBundle::South: - os << "S"; - break; - case WireBundle::West: - os << "W"; - break; - default: - os << "X"; - break; - } - os << ": " << std::to_string(port.channel) << ")"; - return os; - } - - GENERATE_TO_STRING(Port) - - friend llvm::raw_ostream &operator<<(llvm::raw_ostream &os, - const Port &port) { - os << to_string(port); - return os; - } - -} Port; - -typedef struct Connect { - Port src; - Port dst; - - bool operator==(const Connect &rhs) const { - return std::tie(src, dst) == std::tie(rhs.src, rhs.dst); - } -} Connect; - -typedef struct DMAChannel { - DMAChannelDir direction; - int channel; - - bool operator==(const DMAChannel &rhs) const { - return std::tie(direction, channel) == std::tie(rhs.direction, rhs.channel); - } -} DMAChannel; - -mlir::ParseResult parseObjectFifoProducerTile( - mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, - BDDimLayoutArrayAttr &dimensions); - -void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, - mlir::Operation *op, mlir::Value tile, - mlir::Attribute dimensions); - -mlir::ParseResult parseObjectFifoConsumerTiles( - mlir::OpAsmParser &parser, - llvm::SmallVector &tiles, - BDDimLayoutArrayArrayAttr &dimensions); - -void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, - mlir::Operation *op, mlir::OperandRange tiles, - mlir::Attribute dimensions); - -int32_t getBufferBaseAddress(mlir::Operation *bufOp); - -} // namespace xilinx::AIE - // include TableGen generated Op definitions #define GET_OP_CLASSES #include "aie/AIEOps.h.inc" namespace xilinx::AIE { +template +inline TileOp getTileOp(T op) { + return llvm::cast(op.getTile().getDefiningOp()); +} -void collectTiles(DeviceOp &device, - llvm::DenseMap &tiles); - -void collectBuffers( - DeviceOp &device, - llvm::DenseMap> &buffers); } // namespace xilinx::AIE -namespace llvm { -// Functions hash just like pointers. -template <> -struct DenseMapInfo { - static xilinx::AIE::ObjectFifoAcquireOp getEmptyKey() { - auto *pointer = DenseMapInfo::getEmptyKey(); - return xilinx::AIE::ObjectFifoAcquireOp::getFromOpaquePointer(pointer); - } - - static xilinx::AIE::ObjectFifoAcquireOp getTombstoneKey() { - auto *pointer = DenseMapInfo::getTombstoneKey(); - return xilinx::AIE::ObjectFifoAcquireOp::getFromOpaquePointer(pointer); - } - - static unsigned getHashValue(xilinx::AIE::ObjectFifoAcquireOp val) { - return hash_value(val.getAsOpaquePointer()); - } - - static bool isEqual(xilinx::AIE::ObjectFifoAcquireOp lhs, - xilinx::AIE::ObjectFifoAcquireOp rhs) { - return lhs == rhs; - } -}; -} // namespace llvm - -namespace llvm { -// Functions hash just like pointers. -template <> -struct DenseMapInfo { - static xilinx::AIE::ObjectFifoCreateOp getEmptyKey() { - auto *pointer = DenseMapInfo::getEmptyKey(); - return xilinx::AIE::ObjectFifoCreateOp::getFromOpaquePointer(pointer); - } - - static xilinx::AIE::ObjectFifoCreateOp getTombstoneKey() { - auto *pointer = DenseMapInfo::getTombstoneKey(); - return xilinx::AIE::ObjectFifoCreateOp::getFromOpaquePointer(pointer); - } - - static unsigned getHashValue(xilinx::AIE::ObjectFifoCreateOp val) { - return hash_value(val.getAsOpaquePointer()); - } - - static bool isEqual(xilinx::AIE::ObjectFifoCreateOp lhs, - xilinx::AIE::ObjectFifoCreateOp rhs) { - return lhs == rhs; - } -}; - -template <> -struct DenseMapInfo { - using FirstInfo = DenseMapInfo; - using SecondInfo = DenseMapInfo; - - static xilinx::AIE::DMAChannel getEmptyKey() { - return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; - } - - static xilinx::AIE::DMAChannel getTombstoneKey() { - return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; - } - - static unsigned getHashValue(const xilinx::AIE::DMAChannel &d) { - return detail::combineHashValue(FirstInfo::getHashValue(d.direction), - SecondInfo::getHashValue(d.channel)); - } - - static bool isEqual(const xilinx::AIE::DMAChannel &lhs, - const xilinx::AIE::DMAChannel &rhs) { - return lhs == rhs; - } -}; - -template <> -struct DenseMapInfo { - using FirstInfo = DenseMapInfo; - using SecondInfo = DenseMapInfo; - - static xilinx::AIE::Port getEmptyKey() { - return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; - } - - static xilinx::AIE::Port getTombstoneKey() { - return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; - } - - static unsigned getHashValue(const xilinx::AIE::Port &d) { - return detail::combineHashValue(FirstInfo::getHashValue(d.bundle), - SecondInfo::getHashValue(d.channel)); - } - - static bool isEqual(const xilinx::AIE::Port &lhs, - const xilinx::AIE::Port &rhs) { - return lhs == rhs; - } -}; - -} // namespace llvm - -template <> -struct std::less { - bool operator()(const xilinx::AIE::Port &a, - const xilinx::AIE::Port &b) const { - return a.bundle == b.bundle ? a.channel < b.channel : a.bundle < b.bundle; - } -}; - -template <> -struct std::hash { - std::size_t operator()(const xilinx::AIE::Port &p) const noexcept { - std::size_t h1 = std::hash{}(p.bundle); - std::size_t h2 = std::hash{}(p.channel); - return h1 ^ h2 << 1; - } -}; - #endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index b268e74e9..cbf241bd6 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -14,7 +14,6 @@ include "AIE.td" include "AIEAttrs.td" include "AIEInterfaces.td" -include "AIETypes.td" include "mlir/IR/CommonAttrConstraints.td" include "mlir/IR/SymbolInterfaces.td" @@ -686,8 +685,8 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] ins SymbolNameAttr:$sym_name, Index:$producerTile, Variadic:$consumerTiles, - AIE_ObjectFifo_Depth:$elemNumber, - TypeAttrOf:$elemType, + AnyAttrOf<[ConfinedAttr]>, ArrayAttr]>:$elemNumber, + TypeAttrOf:$elemType, BDDimLayoutArrayAttr:$dimensionsToStream, BDDimLayoutArrayArrayAttr:$dimensionsFromStreamPerConsumer, DefaultValuedAttr:$via_DMA, @@ -772,7 +771,7 @@ def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { ConfinedAttr]>:$size ); - let results = (outs AIE_ObjectFifoSubviewType:$subview); + let results = (outs AnyMemRef:$subview); let assemblyFormat = [{ attr-dict $objFifo_name `(` $port `,` $size `)` `:` type($subview) @@ -799,7 +798,7 @@ def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { let summary = "ObjectFifoSubview type accessor method"; let arguments = ( - ins AIE_ObjectFifoSubviewType:$subview, + ins AnyMemRef:$subview, ConfinedAttr]>:$index ); diff --git a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt index ce9a70ad1..28cf0b492 100644 --- a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt @@ -53,16 +53,6 @@ iree_tablegen_library( -gen-op-defs AIEOps.cpp.inc ) -iree_tablegen_library( - NAME - AIETypesGen - TD_FILE - AIETypes.td - OUTS - -gen-typedef-decls -typedefs-dialect=AIE AIETypes.h.inc - -gen-typedef-defs -typedefs-dialect=AIE AIETypes.cpp.inc -) - iree_tablegen_library( NAME AIENormalizeAddressSpacesGen @@ -83,7 +73,6 @@ iree_cc_library( ::AIEDialectGen ::AIEInterfacesGen ::AIEOpsGen - ::AIETypesGen # mlir::DataLayout::closest(mlir::Operation*) MLIRDataLayoutInterfaces # mlir::OffsetSizeAndStrideOpInterface::getOffsets() From 78027b208dfe5228bd1da1ccb5700b95c0ba2bd6 Mon Sep 17 00:00:00 2001 From: max Date: Mon, 5 Aug 2024 14:32:28 -0500 Subject: [PATCH 06/12] clean up --- .../plugins/target/AMD-AIE/aie/AIEDialect.h | 203 +++++- .../target/AMD-AIE/aie/AIEInterfaces.td | 43 -- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 358 +---------- compiler/plugins/target/AMD-AIE/aie/AIEX.td | 590 +----------------- .../target/AMD-AIE/aie/AIEXDialect.cpp | 109 +--- .../aie/AMDAIEAssignBufferAddressesBasic.cpp | 10 +- .../aie/AMDAIEAssignBufferDescriptorIDs.cpp | 26 +- .../AMD-AIE/aie/AMDAIEAssignLockIDs.cpp | 4 +- .../AMD-AIE/aie/AMDAIECoreToStandard.cpp | 26 +- .../AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp | 52 +- .../target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp | 2 +- .../AMD-AIE/aie/AMDAIELocalizeLocks.cpp | 16 +- .../aie/AMDAIENormalizeAddressSpaces.cpp | 2 +- .../aie/AMDAIEObjectFifoStatefulTransform.cpp | 54 +- .../target/AMD-AIE/aie/AMDAIEXToStandard.cpp | 5 +- .../AMD-AIE/iree-amd-aie/IR/AMDAIEOps.cpp | 6 +- .../AMD-AIE/iree-amd-aie/Target/AIETarget.cpp | 4 +- .../AMD-AIE/iree-amd-aie/Target/AIETarget.h | 1 + .../iree-amd-aie/Target/AMDAIETargetBCF.cpp | 37 +- .../Target/AMDAIETargetCDODirect.cpp | 72 +-- .../Target/AMDAIETargetLdScript.cpp | 22 +- .../iree-amd-aie/Target/AMDAIETargets.h | 25 +- .../AMD-AIE/iree-amd-aie/Target/XCLBinGen.cpp | 22 +- .../AMDAIEConvertCoreForallToFor.cpp | 2 +- .../AMDAIEDistributeCoresAndObjectFifos.cpp | 16 +- .../Transforms/AMDAIELowerToAIE.cpp | 15 +- .../aie_runtime/iree_aie_runtime.cc | 1 + .../aie_runtime/iree_aie_runtime.h | 18 +- 28 files changed, 441 insertions(+), 1300 deletions(-) diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index ff5e6337a..73ffb5601 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -42,13 +42,6 @@ mlir::StringAttr name(T &op) { llvm::report_fatal_error("couldn't get name"); } -class TileOp; -} // namespace xilinx::AIE - -/// Include the generated interface declarations. -#include "aie/AIEInterfaces.h.inc" - -namespace xilinx::AIE { mlir::LogicalResult myVerifyOffsetSizeAndStrideOp( mlir::OffsetSizeAndStrideOpInterface op); template @@ -60,6 +53,9 @@ struct MyOffsetSizeAndStrideOpInterfaceTrait } }; +/// Include the generated interface declarations. +#include "aie/AIEInterfaces.h.inc" + struct MyOffsetSizeAndStrideOpInterface : ::mlir::OffsetSizeAndStrideOpInterface { template @@ -78,11 +74,198 @@ struct MyOffsetSizeAndStrideOpInterface #include "aie/AIEOps.h.inc" namespace xilinx::AIE { -template -inline TileOp getTileOp(T op) { - return llvm::cast(op.getTile().getDefiningOp()); + +mlir::ParseResult parseObjectFifoProducerTile( + mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, + BDDimLayoutArrayAttr &dimensions) { + std::vector emptyDims = {}; + if (parser.parseOperand(operand)) return mlir::failure(); + if (succeeded(parser.parseOptionalKeyword("toStream"))) { + if (parser.parseCustomAttributeWithFallback( + dimensions)) { + return mlir::failure(); + } + } else { + dimensions = BDDimLayoutArrayAttr::get(parser.getContext(), + llvm::ArrayRef(emptyDims)); + } + return mlir::success(); +} + +void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::Value operand, + BDDimLayoutArrayAttr dimensions) { + printer << operand; + if (!dimensions.empty()) { + printer << " toStream "; + printer.printStrippedAttrOrType(dimensions); + } +} + +mlir::ParseResult parseObjectFifoConsumerTiles( + mlir::OpAsmParser &parser, + llvm::SmallVectorImpl &tiles, + BDDimLayoutArrayArrayAttr &dimensions) { + // parseCommaSeparatedList doesn't handle the missing case for "none", + // so we handle it custom here. + std::vector tileDims = {}; + + auto parseOneOperand = [&]() -> llvm::ParseResult { + if (parser.parseOperand(tiles.emplace_back(), true)) { + return mlir::failure(); + } + // 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 + BDDimLayoutArrayAttr dimAttr = + BDDimLayoutArrayAttr::get(parser.getContext(), {}); + + if (succeeded(parser.parseOptionalKeyword("fromStream"))) { + // If specified, parse actual data layout transform dimensions + if (parser.parseCustomAttributeWithFallback( + dimAttr)) { + return mlir::failure(); + } + } + tileDims.emplace_back(dimAttr); + return mlir::success(); + }; + + if (parser.parseCommaSeparatedList(mlir::AsmParser::Delimiter::None, + parseOneOperand, " in operand list")) + return mlir::failure(); + + dimensions = BDDimLayoutArrayArrayAttr::get(parser.getContext(), tileDims); + return mlir::success(); +} + +void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::OperandRange tiles, + BDDimLayoutArrayArrayAttr dimsPerTileAttr) { + size_t tileIdx = 0; + for (auto tile : tiles) { + printer << tile; + if (dimsPerTileAttr && tileIdx < dimsPerTileAttr.size() && + dimsPerTileAttr[tileIdx] && !dimsPerTileAttr[tileIdx].empty()) { + printer << " fromStream "; + printer.printStrippedAttrOrType(dimsPerTileAttr[tileIdx]); + } + if (tileIdx < tiles.size() - 1) { + printer << ", "; + } + tileIdx++; + } +} + +inline TileOp getTileOp(mlir::Operation &op) { + mlir::Value t = *op.getOperands().begin(); + return llvm::cast(t.getDefiningOp()); +} + +int32_t getBufferElementTypeWidthInBytes(DMABDOp &op) { + return op.getBuffer().getType().getElementTypeBitWidth() / 8; +} + +int32_t getLenInBytes(DMABDOp &op) { + if (std::optional len = op.getLen(); len.has_value()) + return len.value() * getBufferElementTypeWidthInBytes(op); + else + return op.getBuffer().getType().getNumElements() * + getBufferElementTypeWidthInBytes(op); +} + +int32_t getOffsetInBytes(DMABDOp &op) { + return op.getOffset() * getBufferElementTypeWidthInBytes(op); +} + +MemOp getMemOp(TileOp &op) { + auto users = op.getResult().getUsers(); + for (auto user : users) + if (auto memOp = llvm::dyn_cast(*user)) return memOp; + return nullptr; +} + +CoreOp getCoreOp(TileOp &op) { + auto users = op.getResult().getUsers(); + for (auto user : users) + if (auto coreOp = llvm::dyn_cast(*user)) return coreOp; + return nullptr; +} + +void collectBuffers(DeviceOp &device, + llvm::DenseMap> &buffers) { + for (BufferOp buffer : device.getOps()) { + mlir::Operation *tileOp = buffer.getTile().getDefiningOp(); + buffers[tileOp].push_back(buffer); + } } +inline void collectTiles(xilinx::AIE::DeviceOp &device, + llvm::DenseMap &tiles) { + for (auto tile : device.getOps()) { + int getCol = tile.getCol(); + int getRow = tile.getRow(); + tiles[{getCol, getRow}] = tile; + } +} + +int64_t getAllocationSize(BufferOp &op) { + auto type = llvm::cast(op.getType()); + return type.getNumElements() * type.getElementTypeBitWidth() / 8; +} + +mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( + mlir::Operation *op) { + if (auto t = llvm::dyn_cast(op)) { + return mlir::iree_compiler::AMDAIE::getDeviceModel( + static_cast(t.getDevice())); + } + if (auto t = op->getParentOfType()) { + return mlir::iree_compiler::AMDAIE::getDeviceModel( + static_cast(t.getDevice())); + } + llvm::report_fatal_error("couldn't find device model for op"); +} + +uint32_t getAddressGenGranularity() { return 32; }; + +typedef struct DMAChannel { + DMAChannelDir direction; + int channel; + + bool operator==(const DMAChannel &rhs) const { + return std::tie(direction, channel) == std::tie(rhs.direction, rhs.channel); + } +} DMAChannel; + } // namespace xilinx::AIE +namespace llvm { +template <> +struct DenseMapInfo { + using FirstInfo = DenseMapInfo; + using SecondInfo = DenseMapInfo; + + static xilinx::AIE::DMAChannel getEmptyKey() { + return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; + } + + static xilinx::AIE::DMAChannel getTombstoneKey() { + return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; + } + + static unsigned getHashValue(const xilinx::AIE::DMAChannel &d) { + return detail::combineHashValue(FirstInfo::getHashValue(d.direction), + SecondInfo::getHashValue(d.channel)); + } + + static bool isEqual(const xilinx::AIE::DMAChannel &lhs, + const xilinx::AIE::DMAChannel &rhs) { + return lhs == rhs; + } +}; +} // namespace llvm + #endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td index 9aaca09a1..b10b27f14 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td @@ -18,49 +18,6 @@ include "mlir/IR/OpBase.td" include "mlir/IR/EnumAttr.td" include "mlir/IR/OpAsmInterface.td" -def TileElement : OpInterface<"TileElement", [ - DeclareOpInterfaceMethods, - ]> { - let description = [{ - Interface for operations that exist in a TileOp. - }]; - let cppNamespace = "::xilinx::AIE"; - let methods = [ - InterfaceMethod<[{ - Return the Tile where the element is located. - }], - "TileOp", "getTileOp", (ins ), - /*methodBody=*/[{}], - /*defaultImpl=*/[{ - ConcreteOp op = llvm::cast(this->getOperation()); - return cast(op.getTile().getDefiningOp()); - }] - >, - InterfaceMethod<[{ - Return the location of the Tile where the element is located. - }], - "mlir::iree_compiler::AMDAIE::TileLoc", "getTileLoc", (ins ), - /*methodBody=*/[{}], - /*defaultImpl=*/[{ - ConcreteOp op = llvm::cast(this->getOperation()); - return op.getTileOp().getTileLoc(); - }] - >, - ]; - - let extraTraitClassDeclaration = [{ - void getAsmResultNames( - llvm::function_ref setNameFn) { - ConcreteOp op = llvm::cast(this->getOperation()); - std::string nameWithoutDialect = - op.getOperationName().str().substr(op.getOperationName().find('.') + 1); - setNameFn(op.getResult(), nameWithoutDialect + "_" + - std::to_string(getTileLoc().col) + "_" + - std::to_string(getTileLoc().row)); - } - }]; -} - // Don't delete - see AIEDialect::myVerifyOffsetSizeAndStrideOp def MyOffsetSizeAndStrideOpInterface: OpInterfaceTrait<"::xilinx::AIE::MyOffsetSizeAndStrideOpInterface"> {} diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index cbf241bd6..6a7ba40d6 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -40,12 +40,11 @@ def AIE_DeviceOp: AIE_Op<"device", [ def AIE_TileOp: AIE_Op<"tile", [ Pure, - DeclareOpInterfaceMethods, DeclareOpInterfaceMethods ]>, Results<(outs Index:$result)> { let arguments = ( - ins ConfinedAttr]>:$col, - ConfinedAttr]>:$row + ins ConfinedAttr]>:$col, + ConfinedAttr]>:$row ); let summary = "Declare an AIE tile"; @@ -54,17 +53,6 @@ def AIE_TileOp: AIE_Op<"tile", [ }]; let hasVerifier = 1; - - let extraClassDefinition = [{ - void $cppClass::getAsmResultNames( - function_ref 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]> { @@ -73,7 +61,6 @@ def AIE_EndOp: AIE_Op<"end", [Terminator]> { } def AIE_SwitchboxOp: AIE_Op<"switchbox", [ - TileElement, SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index:$result)> { @@ -83,17 +70,13 @@ def AIE_SwitchboxOp: AIE_Op<"switchbox", [ let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; } def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { - let arguments = (ins I32Attr:$col); + let arguments = (ins I8Attr:$col); let summary = "Declare a switch in the PL shim"; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $col `)` regions attr-dict }]; @@ -101,7 +84,6 @@ def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ } def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ - TileElement, SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { @@ -112,35 +94,9 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; } -// def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ -// FlowEndPoint, TileElement, HasValidBDs, -// HasValidDMAChannels -// DeclareOpInterfaceMethods -// ]>, Results<(outs Index)> { -// let arguments = ( -// ins Index:$tile -// ); -// let summary = "Declare a DMA in the PL shim"; -// let regions = (region AnyRegion:$body); -// let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; -// let hasVerifier = 1; -// -// let extraClassDeclaration = [{ -// int colIndex(); -// int rowIndex(); -// TileOp getTileOp(); -// using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; -// }]; -// } - def AIE_CoreOp: AIE_Op<"core", [ - TileElement, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let arguments = ( @@ -154,10 +110,6 @@ def AIE_CoreOp: AIE_Op<"core", [ let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; - let extraClassDeclaration = [{ - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; - let builders = [ OpBuilder<(ins "mlir::Value":$tile), [{ build($_builder, $_state, $_builder.getIndexType(), tile); @@ -168,9 +120,9 @@ def AIE_CoreOp: AIE_Op<"core", [ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { let arguments = ( ins WireBundle:$source_bundle, - ConfinedAttr]>:$source_channel, + ConfinedAttr]>:$source_channel, WireBundle:$dest_bundle, - ConfinedAttr]>:$dest_channel + ConfinedAttr]>:$dest_channel ); let summary = "A circuit-switched connection inside a switchbox"; let assemblyFormat = [{ @@ -182,10 +134,10 @@ def AIE_FlowOp: AIE_Op<"flow", []> { let arguments = ( ins Index:$source, WireBundle:$source_bundle, - ConfinedAttr]>:$source_channel, + ConfinedAttr]>:$source_channel, Index:$dest, WireBundle:$dest_bundle, - ConfinedAttr]>:$dest_channel + ConfinedAttr]>:$dest_channel ); let summary = "A logical circuit-switched connection between cores"; let assemblyFormat = [{ @@ -222,7 +174,7 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ ]>, Results<(outs Index)> { let arguments = ( ins WireBundle:$dest_bundle, - ConfinedAttr]>:$dest_channel, + ConfinedAttr]>:$dest_channel, Variadic:$amsels ); let summary = "Packet switched input connection"; @@ -234,7 +186,7 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"EndOp">]> { let arguments = ( ins WireBundle:$source_bundle, - ConfinedAttr]>:$source_channel + ConfinedAttr]>:$source_channel ); let regions = (region AnyRegion:$rules); let summary = "Packet switched routing rules"; @@ -271,7 +223,7 @@ def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { let arguments = ( ins Index:$tile, WireBundle:$bundle, - ConfinedAttr]>:$channel + ConfinedAttr]>:$channel ); let summary = "A sourceport"; let assemblyFormat = [{ @@ -283,7 +235,7 @@ def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { let arguments = ( ins Index:$tile, WireBundle:$bundle, - ConfinedAttr]>:$channel + ConfinedAttr]>:$channel ); let summary = "A destination port"; let assemblyFormat = [{ @@ -365,9 +317,9 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [ let summary = "An op to start DMA"; let arguments = ( ins DMAChannelDir:$channel_dir, - ConfinedAttr]>:$channel_index, + ConfinedAttr]>:$channel_index, // repeat_count==0 means "do it once" and don't repeat - DefaultValuedAttr:$repeat_count + DefaultValuedAttr:$repeat_count ); let successors = (successor AnySuccessor:$dest, AnySuccessor:$chain); let assemblyFormat = [{ @@ -375,46 +327,9 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [ }]; } -// def AIE_DMAOp: AIE_Op<"dma", [ -// ParentOneOf<["MemOp", "MemTileDMAOp", "ShimDMAOp"]>, -// NoTerminator, -// DeclareOpInterfaceMethods, -// DeclareOpInterfaceMethods -// ]>, Results<(outs I1:$valid)> { -// -// let summary = "An op to describe a set of DMA operations."; -// -// let arguments = ( -// ins DMAChannelDir:$channel_dir, -// ConfinedAttr]>:$channel_index, -// DefaultValuedAttr:$loop, -// // repeat_count==0 means "do it once" and don't repeat -// DefaultValuedAttr:$repeat_count, -// OptionalAttr:$sym_name -// ); -// let regions = (region VariadicRegion>:$bds); -// let assemblyFormat = [{ -// `(` $channel_dir `,` $channel_index `)` -// attr-dict ` ` -// `[`regions`]` -// }]; -// let hasVerifier = 1; -// -// let extraClassDefinition = [{ -// void $cppClass::getAsmResultNames( -// llvm::function_ref setNameFn) { -// if (auto name = getOperation()->getAttrOfType( -// mlir::SymbolTable::getSymbolAttrName())) -// setNameFn(getResult(), name.str()); -// } -// }]; -// } - - // 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", [ - CallableOpInterface, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a memory op"; @@ -422,16 +337,9 @@ def AIE_MemOp: AIE_Op<"mem", [ let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; } -// This op is not actually Callable, but we want to inline code into them, so we have to -// implement CallableOpInterface def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ - CallableOpInterface, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a memtile_dma op"; @@ -439,10 +347,6 @@ def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; } def AIE_NextBDOp: AIE_Op<"next_bd", [ @@ -457,41 +361,25 @@ def AIE_NextBDOp: AIE_Op<"next_bd", [ } def AIE_LockOp: AIE_Op<"lock", [ - TileElement, Pure, - DeclareOpInterfaceMethods + Pure, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a physical lock"; let arguments = ( ins Index:$tile, - OptionalAttr]>>:$lockID, - OptionalAttr:$init, + OptionalAttr]>>:$lockID, + OptionalAttr:$init, OptionalAttr:$sym_name ); let assemblyFormat = [{ `(` $tile (`,` $lockID^ )? `)` attr-dict }]; - let extraClassDeclaration = [{ - void getAsmResultNames( - llvm::function_ref setNameFn) { - if (hasName(*this)) - setNameFn(getResult(), name(*this).str()); - else { - std::string nameWithoutDialect = - getOperationName().str().substr(getOperationName().find('.') + 1); - setNameFn(getResult(), nameWithoutDialect + "_" + - std::to_string(getTileLoc().col) + "_" + - std::to_string(getTileLoc().row)); - } - } - }]; - let builders = [ OpBuilder<(ins "mlir::Value":$tile, "int":$lockID, "int":$init), [{ build($_builder, $_state, $_builder.getIndexType(), tile, - $_builder.getI32IntegerAttr(lockID), - $_builder.getI32IntegerAttr(init), + $_builder.getI8IntegerAttr(lockID), + $_builder.getI8IntegerAttr(init), nullptr ); }]> @@ -504,7 +392,7 @@ def AIE_UseLockOp: AIE_Op<"use_lock", []> { let arguments = ( ins Index:$lock, LockAction:$action, - OptionalAttr:$value, + OptionalAttr:$value, OptionalAttr:$blocking, DefaultValuedOptionalAttr:$acq_en ); @@ -518,156 +406,34 @@ def AIE_UseLockOp: AIE_Op<"use_lock", []> { OpBuilder<(ins "mlir::Value":$lock, "xilinx::AIE::LockAction":$action, "int32_t":$value), [{ - build($_builder, $_state, lock, action, $_builder.getI32IntegerAttr(value), nullptr); + build($_builder, $_state, lock, action, $_builder.getI8IntegerAttr(value), nullptr); }]> ]; } -def AIE_BufferOp: AIE_Op<"buffer", [ - TileElement - ]>, Results<(outs AnyMemRef)> { +def AIE_BufferOp: AIE_Op<"buffer", []>, Results<(outs AnyMemRef)> { let summary = "Declare a buffer"; let arguments = ( ins Index:$tile, OptionalAttr:$sym_name, OptionalAttr:$address, - OptionalAttr:$initial_value, OptionalAttr:$mem_bank ); let results = (outs AnyMemRef:$buffer); let assemblyFormat = [{ - `(` $tile `)` - attr-dict `:` type($buffer) - custom(ref(type($buffer)), $initial_value) + `(` $tile `)` attr-dict `:` type($buffer) }]; let hasVerifier = 1; - - let extraClassDeclaration = [{ - void getAsmResultNames( - llvm::function_ref setNameFn) { - std::string nameWithoutDialect = - getOperationName().str().substr(getOperationName().find('.') + 1); - setNameFn(getResult(), nameWithoutDialect + "_" + - std::to_string(getTileLoc().col) + "_" + - std::to_string(getTileLoc().row)); - } - }]; -} - -def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ - DeclareOpInterfaceMethods - ]>, Results<(outs AnyMemRef)> { - let summary = "Declare a buffer in external memory"; - let arguments = (ins OptionalAttr:$sym_name); - - let results = (outs AnyMemRef:$buffer); - let assemblyFormat = [{ attr-dict `:` type($buffer) }]; - - let extraClassDefinition = [{ - void $cppClass::getAsmResultNames( - llvm::function_ref setNameFn) { - if (hasName(*this)) - setNameFn(getResult(), name(*this).str()); - } - }]; } -// def AIE_EventOp: AIE_Op<"event", []> { -// let summary = "Event instruction"; -// let arguments = (ins ConfinedAttr, IntMaxValue<1>]>:$val); -// let results = (outs); -// let assemblyFormat = [{ -// `(` $val `)` attr-dict -// }]; -// } -// -// def AIE_GetStreamOp: AIE_Op<"get_stream", [ -// HasParent<"CoreOp"> -// ]>, Results<(outs AnyTypeOf<[F32, I32, I<128>]>)> { -// let summary = "An op to read from a stream channel/port of a switchbox"; -// let arguments = (ins AnyInteger:$channel); -// let results = (outs AnyTypeOf<[F32, I32, I<128>]>:$stream_value); -// -// let assemblyFormat = [{ -// `(` $channel `:` type($channel) `)` attr-dict `:` type($stream_value) -// }]; -// -// let extraClassDeclaration = [{ -// bool isWideStream() { return getStreamValue().getType().isInteger(128); } -// bool isFloatStream() { -// return llvm::isa(getStreamValue().getType()); -// } -// }]; -// } -// -// def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { -// let summary = "An op to write to a stream channel/port of a switchbox"; -// let arguments = ( -// ins AnyInteger:$channel, -// AnyTypeOf<[F32, I32, I<128>]>:$stream_value -// ); -// -// let assemblyFormat = [{ -// `(` $channel `:` type($channel) `,` $stream_value `:` type($stream_value) `)` attr-dict -// }]; -// -// let extraClassDeclaration = [{ -// bool isWideStream() { return getStreamValue().getType().isInteger(128); } -// bool isFloatStream() { -// return llvm::isa(getStreamValue().getType()); -// } -// }]; -// } -// -// def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { -// let arguments = ( -// ins Index:$source_tile, -// Index:$dest_tile -// ); -// let summary = "A cascade connection between tiles"; -// let hasVerifier = 1; -// let assemblyFormat = [{ -// `(` $source_tile `,` $dest_tile `)` attr-dict -// }]; -// let extraClassDeclaration = [{ -// TileOp getSourceTileOp(); -// TileOp getDestTileOp(); -// }]; -// } -// -// def AIE_ConfigureCascadeOp: AIE_Op<"configure_cascade", [HasParent<"DeviceOp">]> { -// let summary = "An op to configure the input and output directions of the cascade for a single AIE tile"; -// let arguments = ( -// ins Index:$tile, -// CascadeDir:$inputDir, -// CascadeDir:$outputDir -// ); -// let results = (outs); -// let hasVerifier = 1; -// let assemblyFormat = [{ `(` $tile `,` $inputDir `,` $outputDir `)` attr-dict }]; -// } -// -// def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascade_value)> { -// let summary = "An op to read from a cascading stream from a neighboring core"; -// let hasVerifier = 1; -// let assemblyFormat = [{ `(` `)` attr-dict `:` type($cascade_value) }]; -// } -// -// def AIE_PutCascadeOp: AIE_Op<"put_cascade", [HasParent<"CoreOp">]> { -// let summary = "An op to write to a cascading stream from a neighboring core"; -// let arguments = (ins AnyType:$cascade_value); -// let hasVerifier = 1; -// let assemblyFormat = [{ `(` $cascade_value `:` type($cascade_value) `)` attr-dict }]; -// } - def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp">]> { let summary = "Runtime allocation information for a single shim DMA"; let arguments = ( ins FlatSymbolRefAttr:$sym_name, DMAChannelDir:$channel_dir, - I64Attr:$channel_index, - I64Attr:$col, + I8Attr:$channel_index, + I8Attr:$col, // If this is set we are using the PLIO in this ShimTile DefaultValuedAttr:$plio ); @@ -741,28 +507,6 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { let hasVerifier = 1; } -def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_external_buffers", [ - HasParent<"DeviceOp">, TileElement - ]> { - let summary = "Registers external buffers to given object fifo shim tile(s) to use in the associated shim DMA(s)"; - let arguments = ( - ins FlatSymbolRefAttr:$objFifo_name, - Index:$tile, - Variadic:$externalBuffers - ); - - let assemblyFormat = [{ - attr-dict $objFifo_name `(` $tile `,` `{` $externalBuffers `}` `)` `:` `(` type($externalBuffers) `)` - }]; - - let hasVerifier = 1; - - let extraClassDeclaration = [{ - // No results so just use default impl. - using ::mlir::OpAsmOpInterface::Trait::getAsmResultNames; - }]; -} - def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { let summary = "Acquire operation to lock and return objects of an ObjectFifo"; let arguments = ( @@ -816,50 +560,14 @@ def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { ]; } -// def AIE_ObjectFifoRegisterProcessOp: AIE_Op<"objectfifo.register_process", []> { -// let summary = "Operation that produces the acquire/release patterns for a process registered to an objectFifo"; -// let arguments = ( -// ins ObjectFifoPort:$port, -// FlatSymbolRefAttr:$objFifo_name, -// I32Tensor:$acquirePatternTensor, -// I32Tensor:$releasePatternTensor, -// FlatSymbolRefAttr:$callee, -// Index:$length -// ); -// -// let assemblyFormat = [{ -// attr-dict $objFifo_name `(` -// $port `,` -// $acquirePatternTensor `:` type($acquirePatternTensor) `,` -// $releasePatternTensor `:` type($releasePatternTensor) `,` -// $callee `,` $length -// `)` -// }]; -// -// let hasVerifier = 1; -// -// let extraClassDeclaration = [{ -// ObjectFifoCreateOp getObjectFifo(); -// -// mlir::DenseIntElementsAttr getAcquirePattern() { -// return llvm::cast(getAcquirePatternTensor() -// .getDefiningOp() -// .getValue()); -// } -// -// mlir::DenseIntElementsAttr getReleasePattern() { -// return llvm::cast(getReleasePatternTensor() -// .getDefiningOp() -// .getValue()); -// } -// -// int getProcessLength() { -// return llvm::cast(getLength() -// .getDefiningOp() -// .getValue()) -// .getInt(); -// } -// }]; -// } +def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ + DeclareOpInterfaceMethods + ]>, Results<(outs AnyMemRef)> { + let summary = "Declare a buffer in external memory"; + let arguments = (ins OptionalAttr:$sym_name); + + let results = (outs AnyMemRef:$buffer); + let assemblyFormat = [{ attr-dict `:` type($buffer) }]; +} #endif // AIE_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEX.td b/compiler/plugins/target/AMD-AIE/aie/AIEX.td index 41892b615..91398a402 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEX.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEX.td @@ -25,13 +25,6 @@ include "mlir/IR/CommonAttrConstraints.td" def AIEX_Dialect : Dialect { let name = "aiex"; let cppNamespace = "::xilinx::AIEX"; - let description = [{ - - This is a dialect for experimental work related to AIEngine processors. - The expectation is that new ideas can be developed here before migration - to the more mature AIE dialect. - - }]; } @@ -39,440 +32,8 @@ class AIEX_Op traits = []> : Op; -def AIE_GetTileOp: AIEX_Op<"getTile", []>, Results<(outs Index:$result)> { - let arguments = ( - ins Index:$col, - Index:$row - ); - - let summary = "Get a reference to an AIE tile"; - let description = [{ - Return a reference to an AIE tile, given the column and the row of the tile. - }]; - let assemblyFormat = [{ `(` $col `,` $row `)` attr-dict }]; -} - -def AIE_ConnectionOp: AIEX_Op<"connection", []> { - let arguments = ( - ins Index:$source, - WireBundle:$sourceBundle, - I32Attr:$sourceChannel, - Index:$dest, - WireBundle:$destBundle, - I32Attr:$destChannel - ); - let summary = "A logical circuit-switched connection between cores"; - let description = [{ - The "aie.connection" operation represents a circuit switched connection between two endpoints, usually - "aie.core" operations. During routing, this is replaced by "aie.connect" operations which represent - the programmed connections inside a switchbox, along with "aie.wire" operations which represent - physical connections between switchboxes and other components. Note that while "aie.flow" operations - can express partial routes between tiles, this is not possible with "aie.connection" operations. - - Example: - %22 = aie.tile(2, 2) - %c22 = aie.core(%22) - %11 = aie.tile(1, 1) - %c11 = aie.core(%11) - aie.flow(%c22, "Core" : 0, %c11, "Core" : 1) - - }]; - let assemblyFormat = [{ - `(` $source `,` $sourceBundle `:` $sourceChannel `,` $dest `,` $destBundle `:` $destChannel `)` attr-dict - }]; - let extraClassDeclaration = [{ - int sourceIndex() { return getSourceChannel(); } - int destIndex() { return getDestChannel(); } - }]; -} - -def AIE_MulticastOp: AIEX_Op<"multicast", [SingleBlockImplicitTerminator<"AIE::EndOp">]> { - let arguments = ( - ins Index:$tile, - WireBundle:$bundle, - I32Attr:$channel - ); - let regions = (region AnyRegion:$ports); - let summary = "An abstraction of multicast"; - let description = [{ - An abstraction of broadcast. During place and - route, it will be replaced by multiple flows. - - Example: - ``` - %70 = AIE.tile(7, 0) - %73 = AIE.tile(7, 3) - %74 = AIE.tile(7, 4) - %63 = AIE.tile(6, 3) - %64 = AIE.tile(6, 4) - aiex.multicast(%70, "DMA" : 0){ - aiex.multi_dest<%73, "DMA" : 0> - aiex.multi_dest<%74, "DMA" : 0> - aiex.multi_dest<%63, "DMA" : 0> - aiex.multi_dest<%64, "DMA" : 0> - } - ``` - }]; - let assemblyFormat = [{ `(` $tile `,` $bundle `:` $channel `)` regions attr-dict }]; - let hasVerifier = 1; - let extraClassDeclaration = [{ - int channelIndex() { return getChannel(); } - AIE::Port port() { return {getBundle(), channelIndex()}; } - }]; -} - -def AIE_MultiDestOp: AIEX_Op<"multi_dest", [HasParent<"MulticastOp">]> { - let arguments = ( - ins Index:$tile, - WireBundle:$bundle, - I32Attr:$channel - ); - let summary = "A destination port of multicast flow"; - let description = [{ - An object representing the destination of a multicast flow. This must exist - within an [aiex.multicast] operation. There can be multiple destinations within an - aiex.multicast Op. - - See [aiex.multicast]for an example. - }]; - let assemblyFormat = [{ - `<` $tile `,` $bundle `:` $channel `>` attr-dict - }]; - let extraClassDeclaration = [{ - int channelIndex() { return getChannel(); } - AIE::Port port() { return {getBundle(), channelIndex()}; } - }]; -} - -def AIE_BroadcastPacketOp: AIEX_Op<"broadcast_packet", [SingleBlockImplicitTerminator<"AIE::EndOp">]> { - let arguments = ( - ins Index:$tile, - WireBundle:$bundle, - I32Attr:$channel - ); - let regions = (region AnyRegion:$ports); - let summary = "Combination of broadcast and packet-switch"; - let description = [{ - An abstraction of broadcast and packet-switched flow. During place and - route, it will be replaced by packet-switched flow and further replaced - by MasterSets and PacketRules inside switchboxes. - - Example: - ``` - %70 = AIE.tile(7, 0) - %73 = AIE.tile(7, 3) - %74 = AIE.tile(7, 4) - %63 = AIE.tile(6, 3) - %64 = AIE.tile(6, 4) - AIE.broadcast_packet(%70, "DMA" : 0){ - AIE.bp_id(0x0){ - AIE.bp_dest<%73, "DMA" : 0> - AIE.bp_dest<%63, "DMA" : 0> - } - AIE.bp_id(0x1){ - AIE.bp_dest<%74, "DMA" : 0> - AIE.bp_dest<%64, "DMA" : 0> - } - } - ``` - }]; - let assemblyFormat = [{ `(` $tile `,` $bundle `:` $channel `)` regions attr-dict }]; - let hasVerifier = 1; - let extraClassDeclaration = [{ - int channelIndex() { return getChannel(); } - AIE::Port port() { return {getBundle(), channelIndex()}; } - }]; -} - -def AIE_BPIDOp: AIEX_Op<"bp_id", [SingleBlockImplicitTerminator<"AIE::EndOp">]> { - let arguments = (ins I8Attr:$ID); - let regions = (region AnyRegion:$ports); - let summary = "A set of packets that share the same ID"; - let description = [{ - A set of destination packets that share the same source and ID. This must exist - within an [AIE.broadcast_packet] operation. - See [AIE.broadcast_packet]for an example. - }]; - let assemblyFormat = [{ `(` $ID `)` regions attr-dict }]; - let extraClassDeclaration = [{ - int IDInt() { return getID(); } - }]; -} - -def AIE_BPDestOp: AIEX_Op<"bp_dest", [HasParent<"BPIDOp">]> { - let arguments = ( - ins Index:$tile, - WireBundle:$bundle, - I32Attr:$channel - ); - let summary = "A destination port"; - let description = [{ - An object representing the destination of a Broad Packet. This must exist - within an [AIE.bp_id] operation. - See [AIE.broadcast_packet] for an example. - }]; - let assemblyFormat = [{ - `<` $tile `,` $bundle `:` $channel `>` attr-dict - }]; - let extraClassDeclaration = [{ - int channelIndex() { return getChannel(); } - AIE::Port port() { return {getBundle(), channelIndex()}; } - }]; -} - -def AIE_TokenOp: AIEX_Op<"token", [Symbol]> { - let summary = "Declare a token (a logical lock)"; - let description = [{ - This operation creates a logical lock. We use Symbol so that it can be referenced globally. - Unlike phsical locks, logical locks are unlimited, and we can specify any integer value - associated with a lock. The logical lock is used to manually specify the dependence of tasks, or - core executions. - - The operation can also be generated automatically if the Dependence Analysis can be leveraged. - - Example: - AIE.token(0) {sym_name = "token0"} // Declare token0 with initial value of 0 - - ... - - AIE.useToken @token0("Acquire", 0) // acquire token0 if its value is 0 - - ... - - AIE.useToken @token0("Release", 5) // release token0 and set its value to 5 - - }]; - let arguments = (ins I32Attr:$value); - let assemblyFormat = [{ `(` $value `)` attr-dict }]; - let extraClassDeclaration = [{ - int getTokenValue() { return getValue(); } - }]; -} - -def AIE_UseTokenOp: AIEX_Op<"useToken", []> { - let summary = "acquire/release a logical lock"; - let description = [{ - This operation uses token (logical lock). A logical lock can be acquired or released with a value. - Similar to UseLockOp, this operation can be understood as "blocking" op. - }]; - let arguments = ( - ins FlatSymbolRefAttr:$tokenName, - I32Attr:$value, - LockAction:$action - ); - let assemblyFormat = [{ $tokenName `(` $action `,` $value `)` attr-dict }]; - let hasVerifier = 1; - let extraClassDeclaration = [{ - bool acquire() { return (getAction() == AIE::LockAction::Acquire); } - bool release() { return (getAction() == AIE::LockAction::Release); } - int getTokenValue() { return getValue(); } - }]; -} - -def AIE_MemcpyOp: AIEX_Op<"memcpy", []> { - let summary = "A memcpy op"; - let description = [{ - This operation defines a logical data transfer of a buffer from a source tile to another buffer - from a destination tile. - - This operation should be lowered to Mem ops with DMA setup and Flow ops for routing data from - the source tile to the dest. tile. - }]; - let arguments = ( - ins FlatSymbolRefAttr:$tokenName, - I32Attr:$acqValue, - I32Attr:$relValue, - Index:$srcTile, - AnyMemRef:$srcBuf, - I32Attr:$srcOffset, - I32Attr:$srcLen, - Index:$dstTile, - AnyMemRef:$dstBuf, - I32Attr:$dstOffset, - I32Attr:$dstLen - ); - let assemblyFormat = [{ - $tokenName `(` $acqValue `,` $relValue `)` `(` - $srcTile `:` `<` $srcBuf `,` $srcOffset `,` $srcLen `>` `,` - $dstTile `:` `<` $dstBuf `,` $dstOffset `,` $dstLen `>` `)` - attr-dict `:` `(` type($srcBuf) `,` type($dstBuf) `)` - }]; - let extraClassDeclaration = [{ - int getAcquireTokenValue() { return getAcqValue(); } - int getReleaseTokenValue() { return getRelValue(); } - int getSrcOffsetValue() { return getSrcOffset(); } - int getDstOffsetValue() { return getDstOffset(); } - int getSrcLenValue() { return getSrcLen(); } - int getDstLenValue() { return getDstLen(); } - }]; -} - - - - -/// Experimental Herd operations -def AIE_HerdOp: AIEX_Op<"herd", []>, Results<(outs Index)> { - let summary = "Declare a herd which is a bundle of core organized in a rectangular shape"; - let description = [{ - This operation creates a group of AIE tiles in 2D shape. - - Example: - %herd0 = AIE.herd[1][1] // a single AIE tile. location unknown - %herd1 = AIE.herd[4][1] // a row of four-AIE tile - - The operation can be used in replacement of a TileOp -- in case we want to select a group of - hardware entities (cores, mems, switchboxes) instead of individual entity, and we don't want to - specify their locations just yet. This can be useful if we want to generate parameterizable - code (the column and row values are parameterized). - - Example: - - %herd = AIE.herd[2][2] // a herd of 2x2 AIE tiles - - AIE.core(%herd) { - // all the cores belong to this herd runs the same code - } - }]; - let arguments = ( - ins I32Attr:$width, - I32Attr:$height - ); - let extraClassDeclaration = [{ - int getHerdWidth() { return getWidth(); } - int getHerdHeight() { return getHeight(); } - int getNumAIETiles() { return getHerdWidth() * getHerdHeight(); } - mlir::StringAttr name() { - if (auto attr = getOperation()->getAttrOfType( - mlir::SymbolTable::getSymbolAttrName())) - return attr; - emitOpError("does not have '") - << mlir::SymbolTable::getSymbolAttrName() << "' attribute specified"; - llvm::report_fatal_error("couldn't get name"); - } - }]; - let assemblyFormat = [{ `[` $width `]` `[` $height `]` attr-dict }]; - let builders = [ - OpBuilder<(ins "int":$width, "int":$height), - [{ - build($_builder, $_state, $_builder.getIndexType(), - $_builder.getI32IntegerAttr(width), - $_builder.getI32IntegerAttr(height)); - }]> - ]; -} - -def AIE_PlaceOp: AIEX_Op<"place", []> { - let summary = "A place operation that specifies the relative placement (XY) of one herd to another"; - let description = [{ - A place operation that specifies the relative placement (XY) of one herd to another. - }]; - let arguments = ( - ins Index:$sourceHerd, - Index:$destHerd, - I32Attr:$distX, - I32Attr:$distY - ); - let assemblyFormat = [{ `(` $sourceHerd `,` $destHerd `,` $distX `,` $distY `)` attr-dict }]; - let extraClassDeclaration = [{ - int getDistXValue() { return getDistX(); } - int getDistYValue() { return getDistY(); } - }]; -} - -def AIE_RouteOp: AIEX_Op<"route", []> { - let summary = "A route operation that routes one herd to another"; - let description = [{ - A route operation that routes one herd to another. - }]; - let arguments = ( - ins Index:$sourceHerds, - WireBundle:$sourceBundle, - I32Attr:$sourceChannel, - Index:$destHerds, - WireBundle:$destBundle, - I32Attr:$destChannel - ); - let assemblyFormat = [{ - `(` `<` $sourceHerds `,` $sourceBundle `:` $sourceChannel `>` `,` - `<` $destHerds `,` $destBundle `:` $destChannel `>` `)` attr-dict - }]; - let extraClassDeclaration = [{ - int getSourceChannelValue() { return getSourceChannel(); } - int getDestChannelValue() { return getDestChannel(); } - }]; -} - -def AIE_IterOp: AIEX_Op<"iter", []>, Results<(outs Index)> { - let summary = "An iter operation"; - let description = [{ - This operation generates index values that can be used with the SelectOp to select a group of tiles - from a herd. - - Example: - %iter0 = AIE.iter(0, 15, 1) // 0, 1, 2, ... , 15 - %iter1 = AIE.iter(2, 8, 2) // 2, 4, 6 - }]; - let arguments = ( - ins I32Attr:$start, - I32Attr:$end, - I32Attr:$stride - ); - let assemblyFormat = [{ `(` $start `,` $end `,` $stride `)` attr-dict }]; - let extraClassDeclaration = [{ - int getStartValue() { return getStart(); } - int getEndValue() { return getEnd(); } - int getStrideValue() { return getStride(); } - }]; - let builders = [ - OpBuilder<(ins "int":$start, "int":$end, "int":$stride), [{ - build($_builder, $_state, $_builder.getIndexType(), - $_builder.getI32IntegerAttr(start), - $_builder.getI32IntegerAttr(end), - $_builder.getI32IntegerAttr(stride)); - }]> - ]; -} - -def AIE_SelectOp: AIEX_Op<"select", []>, Results<(outs Index)> { - let summary = "A select operation"; - let description = [{ - This operation selects a group of tiles based on the selected indices. - - Example: - - %herd = AIE.herd[4][4] // a herd of 4x4 tiles - - %ix = AIE.iter(0, 4, 1) // 0, 1, 2, 3 - %iy = AIE.iter(0, 1, 1) // 0 - - %sub_herd = AIE.select(%herd, %ix, %iy) - - The SelectOp in the above example will select the tiles %herd[0][0], %herd[1][0], - %herd[2][0], %herd[3][0] (the first column of the herd). - }]; - let arguments = ( - ins Index:$startHerd, - Index:$iterX, - Index:$iterY - ); - let assemblyFormat = [{ `(` $startHerd `,` $iterX `,` $iterY `)` attr-dict }]; - let builders = [ - OpBuilder<(ins "mlir::Value":$startHerd, "mlir::Value":$iterX, "mlir::Value":$iterY), [{ - build($_builder, $_state, $_builder.getIndexType(), - startHerd, iterX, iterY); - }]> - ]; -} - def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator, HasParent<"AIE::DeviceOp">]> { let summary = "Program the configuration co-processor of the AI Engine array"; - let description = [{ - Instructions in this operation allow for runtime (re-)configuration of the AI Engine array, such as configuring data movement buffer descriptors. - These instructions will execute on the configuration co-processor of the AI Engine array. - - Typically, these instructions include configuring the data transfers between host and AIE array on the shims. - The input arguments are arguments passed in from the host at kernel invocation time. This may include buffers on the host. - }]; let arguments = ( ins OptionalAttr:$sym_name ); @@ -488,67 +49,6 @@ def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ MyOffsetSizeAndStrideOpInterface ]> { let summary = "half DMA operator"; - - let description = [{ - An n-dimensional half DMA operator. - - Programs a DMA on coordinates (`x`, `y`) to access a memory `memref` with an access - pattern specified by `offsets`, `sizes` and `strides` or `static_offsets`, `static_sizes` - and `static_strides`. The operator references the target channel through the `metadata` - symbol and specifies a descriptor `id` to be used, which will become the `bd_id` to be used - when lowered further. The `issue_token` attribute specifies whether the execution of this - operation should issue a token which can be received and read for synchronization purposes. - This `issue_token` attribute is set to `false` by default for `MM2S` for backward compatibility - and **is always set to true for** `S2MM` channels. - - #### `metadata` -- Specifying Tile, Channel, Direction and Linking a `dma_memcpy_nd` to its Other Half - - The `metadata` attribute must point to a symbol referencing a - [`aie.shim_dma_allocation` operation](AIE.html#aiedma_bd-xilinxaiedmabdop). - The tile coordinates of the DMA to configure, the channel number and the direction (`MM2S` or `S2MM`) are taken from this operation. - - To connect the DMA to its other half (i.e. a `MM2S` DMA to its receiving end and a `S2MM` to the sending end), - the user must configure a flow (`aie.flow`) between the tile and channel referenced in the `aie.shim_dma_allocation` and the corresponding other end. - - When using ObjectFIFOs, the `aie.shim_dma_allocation` operations and the `aie.flows` are generated automatically. - The symbol of the `aie.objectfifo` (create) operation can be used directly in `metadata` in this case. - - #### Notes on Synchronization and Reusing Buffer Descriptor IDs - - When the `dma_memcpy_nd` operation executes, it immediately reprograms the buffer descriptor with ID `bd_id` on tile (`x`, `y`), even if that buffer descriptor is currently executing. - Without proper synchronization, this inevitably leads to nondeterministic results. - - Programming a buffer descriptor that is not currently executing is harmless. - Thus, the first `dma_memcpy_nd` call for each `bd_id` requires no synchronization. - - However, if you wish to later re-use a `bd_id` on the same tile, you must wait for the previous buffer descriptor to complete. - The `sync` or `dma_wait` operations can be used for this. - - `sync` blocks until it receives a _task completion token_ (TCT). - To properly synchronize, you must thus configure your BD to issue a TCT using the `issue_token` attribute, then wait on that token before reusing the BD. - - `dma_wait` is a convenience operation that lowers to the corresponding `sync` operation for the refrenced symbol. - - Note that if you have multiple concurrently running BDs and you can reason one BD will always complete after all others, it is not strictly necessary to issue and wait on the TC token for every BD. - For example, if you have input and output BDs on the shim, and you know the cores will only push output onto the output BD after the input BDs have completed, it may be sufficient to synchronize only on the output BD before reusing input BDs. - - #### Data Layout Transformations - - The `sizes` and `strides` attributes describe a data layout transformation to be performed by the DMA. - These transformations are described in more depth in the documentation for the - [`aie.dma_bd` operation](AIE.html#aiedma_bd-xilinxaiedmabdop). - Note that the syntax here differs from that of the `dma_bd` operation: - offsets and strides are given as separate arrays instead of tuples. - - The `offsets` array is used to calculate a static offset into the memref. - Each offset in the array is understood in relation to the shape of the memref; - the lowest-dimension `offset` is a direct offset in units of memref element type, and the higher dimensions are multiplied by the size of the memref in those dimensions. - Note that this is for convenience of the user only. - The hardware only supports a single static offset, and this offset is calculated at compile time. - Thus, all offsets can be equivalently expressed with the lowest dimension only. - - }]; - let arguments = ( ins I64Attr:$x, I64Attr:$y, @@ -576,32 +76,9 @@ def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ let extraClassDeclaration = [{ static unsigned getOffsetSizeAndStrideStartOperandIndex(); static std::array getArrayAttrMaxRanks(); - - /* Returns the provided multi-dimensional data transfer strides in units of - address granularity. In the IR, we express strides in units of element - data type, but the hardware requires it in units of address granularity. - Address granularity currently is 4 bytes for all hardware. - - The returned stride[0] is the second-lowest dimension stride, i.e. - stride 1. The lowest stride is currently implicitly one, but this is not - a hardware requirement and could be changed in the future. */ llvm::SmallVector getStridesInAddressGranularity(); - - /* Returns the multi-dimensional data transfer sizes in units of address - granularity. These sizes are expressed in units of element data type in - the IR, but the hardware requires them to be in units of address - granularity. Address granularity currently is 4 bytes for all hardware. - - The returned size[0] is the lowest dimension size. In the IR, the sizes - are given in reverse order. For example, specifying sizes in IR as - [1, 2, 3, 4] would result in this function returning [4, 3, 2, 1]. - */ llvm::SmallVector getSizesInAddressGranularity(); - - /* Returns the data transfer offset in bytes, i.e. the first N bytes of the - target buffer will be skipped. In the IR, offsets are expressed in units - of memref element data type size. */ - int64_t getOffsetInBytes(); + int64_t getOffsetInBytes(); }]; let extraClassDefinition = [{ @@ -614,28 +91,6 @@ def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { let summary = "Blocking operation to wait for a DMA to complete execution."; - let description = [{ - The NpuDmaWaitOp blocks until the DMA referenced through `symbol` completes execution - and issues a task-complete-token (TCT). - - `symbol` is a reference to a `aie.shim_dma_allocation`, which contains information about the column, channel and channel direction on which to wait for a TCT. - The `aie.shim_dma_allocation` may be generated from an ObjectFIFO, in which case you can directly pass the ObjectFIFO symbol refrence. - `npu.dma_wait` will be lowered to the corresponding `npu.sync` operation using the information from `symbol`. - - Example: - ```mlir - ... - aie.objectfifo @out0(%tile_0_1, {% raw %}{%tile_0_0}{% endraw %}, 4 : i32) : !aie.objectfifo> - ... - aiex.npu.dma_memcpy_nd(0, 0, %arg2[1, 1, 0, 0][1, 1, 32, 32][1, 1, 64, 1]) {id = 0 : i64, issue_token = true, metadata = @out0} : memref<32x64xi32> - ... - aiex.npu.dma_wait { symbol = @out0 } - ``` - Here, we have an objectfifo with symbol name `out0`, which is then referenced in the - `npu.dma_memcpy_nd` operation as the target for the respective DMA operation. Afterwards, - an `npu.dma_wait` operation references the same symbol to block until the respective DMA - has executed all of its tasks. - }]; let arguments = ( ins FlatSymbolRefAttr:$symbol ); @@ -645,7 +100,6 @@ def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { let hasVerifier = 1; } -// Write RTP def AIE_NpuWriteRTPOp: AIEX_Op<"npu.rtp_write", []> { let summary = "rtp write operator"; let arguments = ( @@ -654,14 +108,9 @@ def AIE_NpuWriteRTPOp: AIEX_Op<"npu.rtp_write", []> { I32Attr:$value ); let results = (outs ); - let assemblyFormat = [{ `(` $buffer `,` $index `,` $value `)` attr-dict - }]; - let description = [{ - rtp write operator - }]; + let assemblyFormat = [{ `(` $buffer `,` $index `,` $value `)` attr-dict }]; } -// Push BD to Queue def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue", []> { let summary = "bd queue push operator"; let arguments = ( @@ -683,7 +132,6 @@ def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue", []> { }]; } -// WRITE32 def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> { let summary = "write32 operator"; let arguments = ( @@ -697,18 +145,8 @@ def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> { let assemblyFormat = [{ attr-dict }]; - let description = [{ - NPU write32 operator writes a 32bit value to the AIE array. - If 'buffer' is present then 'address' is interpreted as an offset into the - aie.buffer with symbol name 'buffer'. - If 'column' and 'row' are present then 'address' is interpreted as an offset - into the memory space of aie.tile(column, row). - If 'buffer' is not present and 'column' and 'row' are not present then - 'address' is interpreted as a full 32-bit address in the AIE array. - }]; } -// BLOCKWRITE def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite", []> { let summary = "blockwrite operator"; let arguments = ( @@ -722,15 +160,6 @@ def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite", []> { let assemblyFormat = [{ `(` $data `)` attr-dict `:` type($data) }]; - let description = [{ - blockwrite operator writes the data from the memref 'data' to the AIE array. - If 'buffer' is present then 'address' is interpreted as an offset into the - aie.buffer with symbol name 'buffer'. - If 'column' and 'row' are present then 'address' is interpreted as an offset - into the memory space of aie.tile(column, row). - If 'buffer' is not present and 'column' and 'row' are not present then - 'address' is interpreted as a full 32-bit address in the AIE array. - }]; } // OP_SYNC @@ -748,17 +177,8 @@ def AIE_NpuSyncOp: AIEX_Op<"npu.sync", []> { let assemblyFormat = [{ attr-dict }]; - let description = [{ - The sync operation blocks execution of the instruction stream until a task-complete token (TCT) is received on `column`, `row`, channel `channel`, direction `direction` (where `0` is `S2MM` and `1` is `MM2S`). - - #### Troubleshooting - - If this operation appears to deadlock, ensure that at least one buffer descriptor is configured to issue a TCT on the channel you expect. - By default, `dma_memcpy_nd` operations only issue tokens for `S2MM` channels, and `issue_token` must be set to `true` to issue tokens for `MM2S` channels. - }]; } -// XAIE_IO_CUSTOM_OP_BEGIN + 1 (address patch) def AIE_NpuAddressPatchOp: AIEX_Op<"npu.address_patch", []> { let summary = "address patch operator"; let arguments = ( @@ -770,9 +190,6 @@ def AIE_NpuAddressPatchOp: AIEX_Op<"npu.address_patch", []> { let assemblyFormat = [{ attr-dict }]; - let description = [{ - address patch operator - }]; } // NPU Bd Write operation @@ -808,9 +225,6 @@ def AIE_NpuWriteBdOp: AIEX_Op<"npu.writebd", []> { let results = (outs ); let assemblyFormat = [{ attr-dict }]; let hasVerifier = 1; - let description = [{ - writebd operator - }]; } #endif // AIEX_OPS \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp index 2b1cbf9f4..9d152bdeb 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp @@ -16,6 +16,7 @@ using namespace mlir; using namespace xilinx; +using namespace xilinx::AIE; #include "aie/AIEXDialect.cpp.inc" @@ -29,51 +30,19 @@ void AIEXDialect::initialize() { >(); } -} // namespace xilinx::AIEX +} // namespace xilinx::AIEX #define GET_OP_CLASSES #include "aie/AIEX.cpp.inc" -LogicalResult AIEX::UseTokenOp::verify() { - auto *parentOp = (*this)->getParentOp(); - if (isa(parentOp) || isa(parentOp) || - isa(parentOp) || isa(parentOp)) - return success(); - return failure(); -} - -LogicalResult AIEX::MulticastOp::verify() { - Region &body = getPorts(); - assert(getOperation()->getNumRegions()); - assert(!body.empty()); - for (auto &ops : body.front()) - if (!isa(ops)) - return ops.emitOpError("cannot be contained in a Multicast op"); - - return success(); -} - -LogicalResult AIEX::BroadcastPacketOp::verify() { - Region &body = getPorts(); - assert(getOperation()->getNumRegions()); - assert(!body.empty()); - for (auto &ops : body.front()) - if (!isa(ops)) - return ops.emitOpError("cannot be contained in a BroadcastPacket op"); - - return success(); -} - llvm::SmallVector AIEX::NpuDmaMemcpyNdOp::getStridesInAddressGranularity() { - const auto &targetModel = AIE::getTargetModel(*this); MemRefType buffer = getMemref().getType(); auto elemWidth = buffer.getElementTypeBitWidth(); - auto addressGranularity = targetModel.getAddressGenGranularity(); - llvm::SmallVector strides = - llvm::map_to_vector(llvm::reverse(getMixedStrides()), [](OpFoldResult s) { - return getConstantIntValue(s).value(); - }); + auto addressGranularity = getAddressGenGranularity(); + llvm::SmallVector strides = llvm::map_to_vector( + llvm::reverse(getMixedStrides()), + [](OpFoldResult s) { return getConstantIntValue(s).value(); }); if (!strides.empty()) { for (int i = 0; i < 4; i++) { strides[i] = (strides[i] * elemWidth) / addressGranularity; @@ -84,14 +53,12 @@ AIEX::NpuDmaMemcpyNdOp::getStridesInAddressGranularity() { llvm::SmallVector AIEX::NpuDmaMemcpyNdOp::getSizesInAddressGranularity() { - const auto &targetModel = AIE::getTargetModel(*this); MemRefType buffer = getMemref().getType(); auto elemWidth = buffer.getElementTypeBitWidth(); - auto addressGranularity = targetModel.getAddressGenGranularity(); - llvm::SmallVector sizes = - llvm::map_to_vector(llvm::reverse(getMixedSizes()), [](OpFoldResult s) { - return getConstantIntValue(s).value(); - }); + auto addressGranularity = getAddressGenGranularity(); + llvm::SmallVector sizes = llvm::map_to_vector( + llvm::reverse(getMixedSizes()), + [](OpFoldResult s) { return getConstantIntValue(s).value(); }); if (!sizes.empty()) { sizes[0] = (sizes[0] * elemWidth) / addressGranularity; } @@ -101,10 +68,9 @@ AIEX::NpuDmaMemcpyNdOp::getSizesInAddressGranularity() { /* Calculates the offset value to be written to the */ int64_t AIEX::NpuDmaMemcpyNdOp::getOffsetInBytes() { - llvm::SmallVector offsets = - llvm::map_to_vector(llvm::reverse(getMixedOffsets()), [](OpFoldResult s) { - return getConstantIntValue(s).value(); - }); + llvm::SmallVector offsets = llvm::map_to_vector( + llvm::reverse(getMixedOffsets()), + [](OpFoldResult s) { return getConstantIntValue(s).value(); }); size_t stride = 1; size_t offset = 0; MemRefType my_memref = getMemref().getType(); @@ -123,8 +89,8 @@ int64_t AIEX::NpuDmaMemcpyNdOp::getOffsetInBytes() { LogicalResult AIEX::NpuDmaMemcpyNdOp::verify() { MemRefType buffer = getMemref().getType(); - const auto &targetModel = AIE::getTargetModel(*this); - auto addressGranularity = targetModel.getAddressGenGranularity(); + const auto &targetModel = getDeviceModel(*this); + auto addressGranularity = getAddressGenGranularity(); auto elemWidth = buffer.getElementTypeBitWidth(); if (buffer.getElementTypeBitWidth() > addressGranularity) { @@ -148,36 +114,29 @@ LogicalResult AIEX::NpuDmaMemcpyNdOp::verify() { })) return emitOpError("Only constant offsets currently supported."); - llvm::SmallVector raw_strides = - llvm::map_to_vector(llvm::reverse(getMixedStrides()), [](OpFoldResult s) { - return getConstantIntValue(s).value(); - }); - llvm::SmallVector raw_sizes = - llvm::map_to_vector(llvm::reverse(getMixedSizes()), [](OpFoldResult s) { - return getConstantIntValue(s).value(); - }); + llvm::SmallVector raw_strides = llvm::map_to_vector( + llvm::reverse(getMixedStrides()), + [](OpFoldResult s) { return getConstantIntValue(s).value(); }); + llvm::SmallVector raw_sizes = llvm::map_to_vector( + llvm::reverse(getMixedSizes()), + [](OpFoldResult s) { return getConstantIntValue(s).value(); }); llvm::SmallVector strides = getStridesInAddressGranularity(); llvm::SmallVector sizes = getSizesInAddressGranularity(); int64_t offset = getOffsetInBytes(); - // The experimental HSA target uses this op on AIE1, skip all the AIE2 - // specific checks - if (targetModel.getTargetArch() == AIE::AIEArch::AIE1) - return success(); - uint32_t wrap_bits = 0; uint32_t step_bits = 0; uint32_t iter_bits = 6; if (targetModel.isShimNOCTile(getX(), getY())) { - step_bits = 20; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_STEPSIZE_WIDTH - wrap_bits = 10; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_WRAP_WIDTH + step_bits = 20; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_STEPSIZE_WIDTH + wrap_bits = 10; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_WRAP_WIDTH } else if (targetModel.isMemTile(getX(), getY())) { - step_bits = 17; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH - wrap_bits = 10; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_WRAP_WIDTH + step_bits = 17; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH + wrap_bits = 10; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_WRAP_WIDTH } else if (targetModel.isCoreTile(getX(), getY())) { - step_bits = 13; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH - wrap_bits = 8; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_3_D0_WRAP_WIDTH + step_bits = 13; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH + wrap_bits = 8; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_3_D0_WRAP_WIDTH } else { return emitOpError("Unsupported tile type at (" + std::to_string(getX()) + ", " + std::to_string(getY()) + @@ -212,8 +171,7 @@ LogicalResult AIEX::NpuDmaMemcpyNdOp::verify() { for (int i = 0; i < 4; i++) { // strides[0] == 1 is ok iff the tranfer size is a multiple of // addressGranularity, which is checked below - if (i == 0 && raw_strides[i] == 1) - continue; + if (i == 0 && raw_strides[i] == 1) continue; if (raw_strides[i] * elemWidth % addressGranularity != 0) { std::stringstream msg; msg << "Stride " << i << " is " << raw_strides[i] << " elements * " @@ -247,20 +205,18 @@ LogicalResult AIEX::NpuDmaWaitOp::verify() { } LogicalResult AIEX::NpuPushQueueOp::verify() { - const auto &targetModel = AIE::getTargetModel(*this); + const auto &targetModel = getDeviceModel(*this); auto numBds = targetModel.getNumBDs(getColumn(), getRow()); - if (getBdId() > numBds) - return emitOpError("BD ID exceeds the maximum ID."); + if (getBdId() > numBds) return emitOpError("BD ID exceeds the maximum ID."); if (getRepeatCount() > 255) return emitOpError("Repeat count exceeds the [0:255] range."); return success(); } LogicalResult AIEX::NpuWriteBdOp::verify() { - const auto &targetModel = AIE::getTargetModel(*this); + const auto &targetModel = getDeviceModel(*this); auto numBds = targetModel.getNumBDs(getColumn(), getRow()); - if (getBdId() > numBds) - return emitOpError("BD ID exceeds the maximum ID."); + if (getBdId() > numBds) return emitOpError("BD ID exceeds the maximum ID."); if (getD0Size() > 0x3FF) return emitOpError("D0 Size exceeds the [0:1023] range."); if (getD0Stride() > 0xFFFFF) @@ -284,7 +240,6 @@ LogicalResult AIEX::NpuWriteBdOp::verify() { ParseResult AIEX::RuntimeSequenceOp::parse(OpAsmParser &parser, OperationState &result) { - StringAttr nameAttr; (void)parser.parseOptionalSymbolName( nameAttr, mlir::SymbolTable::getSymbolAttrName(), result.attributes); diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp index ed8946d6f..7e3ea3bc3 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferAddressesBasic.cpp @@ -4,8 +4,8 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/Twine.h" #include "mlir/IR/Attributes.h" @@ -41,13 +41,13 @@ struct AMDAIEAssignBufferAddressesPassBasic : mlir::OperationPass { DeviceOp device = getOperation(); int counter = 0; device.walk([&](BufferOp buffer) { - if (!buffer.hasName()) + if (!hasName(buffer)) buffer.setSymName("_anonymous" + std::to_string(counter++)); }); DenseMap> tileToBuffers; device.walk([&](BufferOp buffer) { - tileToBuffers[buffer.getTileOp()].insert(buffer); + tileToBuffers[getTileOp(*buffer)].insert(buffer); }); AMDAIEDeviceModel deviceModel = mlir::iree_compiler::AMDAIE::getDeviceModel( @@ -55,11 +55,11 @@ struct AMDAIEAssignBufferAddressesPassBasic : mlir::OperationPass { for (auto [tile, buffers] : tileToBuffers) { // Leave room at the bottom of the address range for stack int64_t address = 0; - if (auto core = tile.getCoreOp()) address += core.getStackSize(); + if (auto core = getCoreOp(tile)) address += core.getStackSize(); for (auto buffer : buffers) { buffer.setAddress(address); - address += buffer.getAllocationSize(); + address += getAllocationSize(buffer); } int maxDataMemorySize; diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp index 8c3d7362a..890e61e01 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignBufferDescriptorIDs.cpp @@ -7,8 +7,8 @@ #include #include -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/Utils/ChannelBdIdGenerator.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "mlir/Pass/Pass.h" @@ -34,15 +34,12 @@ LogicalResult assignBdIds(DeviceOp deviceOp) { ChannelBdIdGenerator memTileChannelBdIdGenerator( deviceModel.getChannelToValidBdIds(AMDAIETileType::MEMTILE)); - auto memOps = llvm::to_vector_of(deviceOp.getOps()); + auto memOps = llvm::to_vector_of(deviceOp.getOps()); llvm::append_range(memOps, deviceOp.getOps()); - llvm::append_range(memOps, deviceOp.getOps()); - for (TileElement memOp : memOps) { - int col = memOp.getTileLoc().col; - int row = memOp.getTileLoc().row; - + for (Operation *memOp : memOps) { + TileOp t = getTileOp(*memOp); // BdIdGenerator gen(col, row, deviceModel); - ChannelBdIdGenerator gen = deviceModel.isMemTile(col, row) + ChannelBdIdGenerator gen = deviceModel.isMemTile(t.getCol(), t.getRow()) ? memTileChannelBdIdGenerator : shimChannelBdIdGenerator; @@ -53,7 +50,7 @@ LogicalResult assignBdIds(DeviceOp deviceOp) { DenseMap blockChannelMap; // Associate with each block the channel index specified by the // dma_start - for (Block &block : memOp.getOperation()->getRegion(0)) + for (Block &block : memOp->getRegion(0)) for (auto op : block.getOps()) { int chNum = op.getChannelIndex(); blockChannelMap[&block] = chNum; @@ -66,7 +63,7 @@ LogicalResult assignBdIds(DeviceOp deviceOp) { } } - for (Block &block : memOp.getOperation()->getRegion(0)) { + for (Block &block : memOp->getRegion(0)) { if (block.getOps().empty()) continue; assert(blockChannelMap.count(&block)); DMABDOp bd = (*block.getOps().begin()); @@ -77,15 +74,16 @@ LogicalResult assignBdIds(DeviceOp deviceOp) { std::optional bdId = gen.getAndAssignBdId(blockChannelMap[&block]); if (!bdId) - return memOp.emitOpError() + return memOp->emitOpError() << "could not find and assign a valid BD id"; bd.setBdId(bdId.value()); } } } - for (TileElement memOp : memOps) { + + for (Operation *memOp : memOps) { DenseMap blockBdIdMap; - for (Block &block : memOp.getOperation()->getRegion(0)) { + for (Block &block : memOp->getRegion(0)) { if (block.getOps().empty()) continue; DMABDOp bd = *block.getOps().begin(); assert(bd.getBdId().has_value() && @@ -93,7 +91,7 @@ LogicalResult assignBdIds(DeviceOp deviceOp) { blockBdIdMap[&block] = bd.getBdId().value(); } - for (Block &block : memOp.getOperation()->getRegion(0)) { + for (Block &block : memOp->getRegion(0)) { if (block.getOps().empty()) continue; DMABDOp bd = *block.getOps().begin(); std::optional nextBdId; diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp index 6a59792fa..5636c2079 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp @@ -11,8 +11,8 @@ // independently. If there are existing lock IDs, this pass is idempotent // and only assigns lock IDs to locks without an ID. -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/DenseMap.h" #include "mlir/Pass/Pass.h" @@ -55,7 +55,7 @@ struct AMDAIEAssignLockIDsPass : mlir::OperationPass { // Construct data structure storing locks by tile. device.walk([&](LockOp lockOp) { - TileOp tileOp = lockOp.getTileOp(); + TileOp tileOp = xilinx::AIE::getTileOp(*lockOp); if (lockOp.getLockID().has_value()) { auto lockID = lockOp.getLockID().value(); auto iter = tileToLocks.find(tileOp); diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp index bce8708dd..46ee4aedb 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIECoreToStandard.cpp @@ -4,8 +4,8 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVM.h" #include "mlir/Conversion/FuncToLLVM/ConvertFuncToLLVMPass.h" #include "mlir/Dialect/Arith/IR/Arith.h" @@ -35,9 +35,10 @@ struct AMDAIEUseLockToStdLowering : OpConversionPattern { if (!isa(useLock->getParentOp())) { // Generate the intrinsic name std::string funcName = "llvm.aie2."; - if (useLock.acquire() || useLock.acquireGE()) + if (useLock.getAction() == LockAction::Acquire || + useLock.getAction() == LockAction::AcquireGreaterEqual) funcName += "acquire"; - else if (useLock.release()) + else if (useLock.getAction() == LockAction::Release) funcName += "release"; // TODO(max): this can be simplified with // SymbolTable::lookupNearestSymbolFrom if DeviceOp ceases to be a @@ -47,10 +48,11 @@ struct AMDAIEUseLockToStdLowering : OpConversionPattern { funcName); SmallVector args; - int lockValue = useLock.getLockValue(); + int lockValue = useLock.getValue().value_or(1); // AIE2 acquire greater equal is encoded as a negative value. - if (useLock.acquireGE()) lockValue = -lockValue; + if (useLock.getAction() == LockAction::AcquireGreaterEqual) + lockValue = -lockValue; args.push_back(rewriter.create( useLock.getLoc(), IntegerType::get(rewriter.getContext(), 32), useLock.getLock())); @@ -84,17 +86,12 @@ struct AMDAIEBufferToStandard : OpConversionPattern { ConversionPatternRewriter &rewriter) const override { rewriter.setInsertionPointToStart(module.getBody()); auto t = llvm::cast(buffer.getType()); - int col = llvm::cast(buffer.getTile().getDefiningOp()).getCol(); - int row = llvm::cast(buffer.getTile().getDefiningOp()).getRow(); - StringRef symName = buffer.name().getValue(); - mlir::ElementsAttr initValue = buffer.getInitialValueAttr(); + StringRef symName = name(buffer).getValue(); // Don't emit initialization for cores that don't "own" the buffer (to // prevent duplication in the data section of the elf/object file) - if ((tileRow != row && tileRow != -1) || (tileCol != col && tileCol != -1)) - initValue = nullptr; rewriter.create( rewriter.getUnknownLoc(), symName, rewriter.getStringAttr("public"), - buffer.getType(), initValue, /*constant*/ false, + buffer.getType(), nullptr, /*constant*/ false, /*alignment*/ nullptr); for (OpOperand &use : make_early_inc_range(buffer.getResult().getUses())) { @@ -131,8 +128,9 @@ struct AMDAIECoreToStandardFunc : OpConversionPattern { LogicalResult matchAndRewrite( CoreOp op, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { - int col = op.colIndex(); - int row = op.rowIndex(); + TileOp t = getTileOp(*op); + int col = t.getCol(); + int row = t.getRow(); // Only pull code for the indicated function if ((tileRow != row && tileRow != -1) || diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp index 2ed54a4e3..7e74227ba 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp @@ -9,8 +9,8 @@ #include #include -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_router.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/DenseMapInfo.h" @@ -28,7 +28,6 @@ using xilinx::AIE::DeviceOp; using xilinx::AIE::DMAChannelDir; using xilinx::AIE::EndOp; using xilinx::AIE::FlowOp; -using xilinx::AIE::Interconnect; using xilinx::AIE::MasterSetOp; using xilinx::AIE::PacketDestOp; using xilinx::AIE::PacketFlowOp; @@ -38,7 +37,6 @@ using xilinx::AIE::PacketSourceOp; using xilinx::AIE::ShimMuxOp; using xilinx::AIE::SwitchboxOp; using xilinx::AIE::TileOp; -using xilinx::AIE::WireOp; #define DEBUG_TYPE "amdaie-create-pathfinder-flows" #define OVER_CAPACITY_COEFF 0.02 @@ -151,7 +149,8 @@ struct ConvertFlowsToInterconnect : OpConversionPattern { FlowOp flowOp, OpAdaptor adaptor, ConversionPatternRewriter &rewriter) const override { auto srcTile = llvm::cast(flowOp.getSource().getDefiningOp()); - TileLoc srcCoords = {srcTile.colIndex(), srcTile.rowIndex()}; + TileLoc srcCoords = {static_cast(srcTile.getCol()), + static_cast(srcTile.getRow())}; StrmSwPortType srcBundle = toStrmT(flowOp.getSourceBundle()); int srcChannel = flowOp.getSourceChannel(); Port srcPort = {srcBundle, srcChannel}; @@ -229,15 +228,15 @@ LogicalResult runOnPacketFlow( const std::map &flowSolutions) { mlir::DenseMap tiles; for (auto tileOp : device.getOps()) { - int col = tileOp.colIndex(); - int row = tileOp.rowIndex(); + int col = tileOp.getCol(); + int row = tileOp.getRow(); tiles[{col, row}] = tileOp; } DenseMap keepPktHeaderAttr; SwitchBoxToConnectionFlowIDT switchboxes; for (PacketFlowOp pktFlowOp : device.getOps()) { - int flowID = pktFlowOp.IDInt(); + int flowID = pktFlowOp.getID(); Port srcPort{StrmSwPortType::SS_PORT_TYPE_MAX, -1}; TileOp srcTile; TileLoc srcCoords{-1, -1}; @@ -246,13 +245,13 @@ LogicalResult runOnPacketFlow( for (Operation &Op : b.getOperations()) { if (auto pktSource = llvm::dyn_cast(Op)) { srcTile = llvm::cast(pktSource.getTile().getDefiningOp()); - srcPort = {toStrmT(pktSource.port().bundle), pktSource.port().channel}; - srcCoords = {srcTile.colIndex(), srcTile.rowIndex()}; + srcPort = {toStrmT(pktSource.getBundle()), + static_cast(pktSource.getChannel())}; + srcCoords = {srcTile.getCol(), srcTile.getRow()}; } else if (auto pktDest = llvm::dyn_cast(Op)) { TileOp destTile = llvm::cast(pktDest.getTile().getDefiningOp()); - Port destPort = {toStrmT(pktDest.port().bundle), - pktDest.port().channel}; - TileLoc destCoord = {destTile.colIndex(), destTile.rowIndex()}; + Port destPort = {toStrmT(pktDest.getBundle()), pktDest.getChannel()}; + TileLoc destCoord = {destTile.getCol(), destTile.getRow()}; if (pktFlowOp->hasAttr("keep_pkt_header")) keepPktHeaderAttr[PhysPort{destCoord, destPort}] = StringAttr::get(Op.getContext(), "true"); @@ -478,10 +477,10 @@ void AIEPathfinderPass::runOnOperation() { std::set processedFlows; // don't be clever and remove these initializations because // then you're doing a max against garbage data... - int maxCol = 0, maxRow = 0; + uint8_t maxCol = 0, maxRow = 0; for (TileOp tileOp : device.getOps()) { - maxCol = std::max(maxCol, tileOp.colIndex()); - maxRow = std::max(maxRow, tileOp.rowIndex()); + maxCol = std::max(maxCol, tileOp.getCol()); + maxRow = std::max(maxRow, tileOp.getRow()); } AMDAIEDeviceModel deviceModel = @@ -493,8 +492,8 @@ void AIEPathfinderPass::runOnOperation() { for (FlowOp flowOp : device.getOps()) { TileOp srcTile = llvm::cast(flowOp.getSource().getDefiningOp()); TileOp dstTile = llvm::cast(flowOp.getDest().getDefiningOp()); - TileLoc srcCoords = {srcTile.colIndex(), srcTile.rowIndex()}; - TileLoc dstCoords = {dstTile.colIndex(), dstTile.rowIndex()}; + TileLoc srcCoords = {srcTile.getCol(), srcTile.getRow()}; + TileLoc dstCoords = {dstTile.getCol(), dstTile.getRow()}; Port srcPort = {toStrmT(flowOp.getSourceBundle()), flowOp.getSourceChannel()}; Port dstPort = {toStrmT(flowOp.getDestBundle()), flowOp.getDestChannel()}; @@ -510,12 +509,12 @@ void AIEPathfinderPass::runOnOperation() { for (Operation &op : b.getOperations()) { if (auto pktSource = llvm::dyn_cast(op)) { srcTile = llvm::cast(pktSource.getTile().getDefiningOp()); - srcPort = {toStrmT(pktSource.port().bundle), pktSource.port().channel}; - srcCoords = {srcTile.colIndex(), srcTile.rowIndex()}; + srcPort = {toStrmT(pktSource.getBundle()), pktSource.getChannel()}; + srcCoords = {srcTile.getCol(), srcTile.getRow()}; } else if (auto pktDest = llvm::dyn_cast(op)) { TileOp dstTile = llvm::cast(pktDest.getTile().getDefiningOp()); - Port dstPort = {toStrmT(pktDest.port().bundle), pktDest.port().channel}; - TileLoc dstCoords = {dstTile.colIndex(), dstTile.rowIndex()}; + Port dstPort = {toStrmT(pktDest.getBundle()), pktDest.getChannel()}; + TileLoc dstCoords = {dstTile.getCol(), dstTile.getRow()}; assert(srcPort.bundle != StrmSwPortType::SS_PORT_TYPE_MAX && srcPort.channel != -1 && "expected srcPort to have been set"); assert(srcCoords.col != -1 && srcCoords.row != -1); @@ -529,13 +528,12 @@ void AIEPathfinderPass::runOnOperation() { for (SwitchboxOp switchboxOp : device.getOps()) { std::vector> connects; for (ConnectOp connectOp : switchboxOp.getOps()) { - connects.emplace_back(toStrmT(connectOp.sourcePort().bundle), - connectOp.sourcePort().channel, - toStrmT(connectOp.destPort().bundle), - connectOp.destPort().channel); + connects.emplace_back( + toStrmT(connectOp.getSourceBundle()), connectOp.getSourceChannel(), + toStrmT(connectOp.getDestBundle()), connectOp.getDestChannel()); } - if (!pathfinder.addFixedConnection(switchboxOp.colIndex(), - switchboxOp.rowIndex(), connects)) { + TileOp t = xilinx::AIE::getTileOp(*switchboxOp.getOperation()); + if (!pathfinder.addFixedConnection(t.getCol(), t.getRow(), connects)) { switchboxOp.emitOpError() << "Unable to add fixed connections"; return signalPassFailure(); } diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp index 2b3ab63c4..f15990681 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEDmaToNpu.cpp @@ -4,9 +4,9 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "Passes.h" #include "AIEDialect.h" #include "AIEXDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp index 94ab2227c..b7dcc9e23 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIELocalizeLocks.cpp @@ -4,8 +4,8 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "Passes.h" #include "AIEDialect.h" +#include "Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Pass/Pass.h" @@ -46,19 +46,19 @@ struct AMDAIELocalizeLocksPass : mlir::OperationPass { for (auto coreOp : deviceOp.getOps()) { // Collect the locks used in this core. auto thisTile = dyn_cast(coreOp.getTile().getDefiningOp()); - int col = thisTile.colIndex(); - int row = thisTile.rowIndex(); + int col = thisTile.getCol(); + int row = thisTile.getRow(); // Find the neighboring tiles SmallVector accessibleTiles; for (auto tile : deviceOp.getOps()) - if (int dstRow = tile.rowIndex(); - deviceModel.hasLegalMemAffinity(col, row, tile.colIndex(), dstRow)) + if (int dstRow = tile.getRow(); + deviceModel.hasLegalMemAffinity(col, row, tile.getCol(), dstRow)) accessibleTiles.push_back(tile); for (auto tile : accessibleTiles) { - int dstCol = tile.colIndex(); - int dstRow = tile.rowIndex(); + int dstCol = tile.getCol(); + int dstRow = tile.getRow(); int cardinalMemOffset = 0; int numLocks = deviceModel.getNumLocks(dstCol, dstRow); for (auto user : tile.getResult().getUsers()) @@ -74,7 +74,7 @@ struct AMDAIELocalizeLocksPass : mlir::OperationPass { else llvm_unreachable("Found illegal lock user!"); - int localLockIndex = cardinalMemOffset + lock.getLockIDValue(); + int localLockIndex = cardinalMemOffset + lock.getLockID().value(); OpBuilder builder = OpBuilder::atBlockBegin(&coreOp.getBody().front()); diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp index 886f3df6e..6d9b6b030 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIENormalizeAddressSpaces.cpp @@ -27,7 +27,7 @@ Type memRefToDefaultAddressSpace(Type t) { return t; } -#include "aie/Dialect/AIE/Transforms/AIENormalizeAddressSpaces.inc" +#include "aie/AIENormalizeAddressSpaces.inc" } // namespace diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp index 2beb30db2..cba0548c5 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp @@ -26,7 +26,6 @@ using namespace mlir; using namespace mlir::iree_compiler::AMDAIE; -using xilinx::AIE::AIEObjectFifoType; using xilinx::AIE::BDDimLayoutArrayArrayAttr; using xilinx::AIE::BDDimLayoutArrayAttr; using xilinx::AIE::BDDimLayoutAttr; @@ -37,7 +36,6 @@ using xilinx::AIE::DMABDOp; using xilinx::AIE::DMAChannelDirAttr; using xilinx::AIE::DMAStartOp; using xilinx::AIE::EndOp; -using xilinx::AIE::ExternalBufferOp; using xilinx::AIE::FlowOp; using xilinx::AIE::LockAction; using xilinx::AIE::LockOp; @@ -48,7 +46,6 @@ using xilinx::AIE::ObjectFifoAcquireOp; using xilinx::AIE::ObjectFifoCreateOp; using xilinx::AIE::ObjectFifoLinkOp; using xilinx::AIE::ObjectFifoPort; -using xilinx::AIE::ObjectFifoRegisterExternalBuffersOp; using xilinx::AIE::ObjectFifoReleaseOp; using xilinx::AIE::ObjectFifoSubviewAccessOp; using xilinx::AIE::ShimDMAAllocationOp; @@ -426,9 +423,8 @@ void createAMDAIETileDMA( if (objFifoLinks.contains(linkOp.value())) target = objFifoLinks.at(linkOp.value()); - auto fifo = llvm::cast(createOp.getElemType()); - auto elemType = llvm::cast(fifo.getElementType()); - int64_t len = elemType.getNumElements(); + auto fifo = createOp.getElemType(); + int64_t len = fifo.getNumElements(); createDMA(device, builder, createOp, target, channelDir, channelIndex, dims, numBlocks, /*acqNum*/ 1, /*relNum*/ 1, len, /*offset*/ 0, @@ -446,9 +442,8 @@ void createMemTileDMA( size_t numBlocks = objFifoSize(createOp); if (numBlocks == 0) return; - auto fifo = llvm::cast(createOp.getElemType()); - auto elemType = llvm::cast(fifo.getElementType()); - int64_t lenOut = elemType.getNumElements(); + auto fifo = createOp.getElemType(); + int64_t lenOut = fifo.getNumElements(); size_t acqNum = 1; size_t relNum = 1; // offset based on order of this op in join/distribute list @@ -464,10 +459,9 @@ void createMemTileDMA( relNum = size; } else for (auto fifoIn : fifos) { - auto fifoType = llvm::cast(fifoIn.getElemType()); - auto fifoElemType = llvm::cast(fifoType.getElementType()); + auto fifoType = fifoIn.getElemType(); if (name(fifoIn) == name(createOp)) break; - extraOffset += fifoElemType.getNumElements(); + extraOffset += fifoType.getNumElements(); } }; @@ -486,9 +480,8 @@ void createMemTileDMA( linkOp->getFifoOuts().size()); } else if (target != createOp) { - auto targetFifo = llvm::cast(target.getElemType()); - auto targetElemType = llvm::cast(targetFifo.getElementType()); - lenOut = targetElemType.getNumElements(); + auto targetFifo = target.getElemType(); + lenOut = targetFifo.getNumElements(); } // check if current createOp is of smaller size in link @@ -566,8 +559,8 @@ void createUseLocks( builder.create(builder.getUnknownLoc(), lock, lockAction, numLocks); std::pair opPort = {op, static_cast(port)}; - acc[opPort] = (acc[opPort] + numLocks) % - objFifoSize(op); // update to next objFifo elem + // update to next objFifo elem + acc[opPort] = (acc[opPort] + numLocks) % objFifoSize(op); } /// Replace (not really - add) ObjectFifoReleaseOp with appropriate UseLockOp. @@ -629,7 +622,7 @@ void splitFifo( }; int consumerIndex = 0; - auto datatype = cast(createOp.getElemType()); + auto datatype = createOp.getElemType(); MLIRContext *ctx = builder.getContext(); std::vector splitConsumerFifos; for (auto consumerTile : createOp.getConsumerTiles()) { @@ -835,8 +828,7 @@ void createBuffersAndLocks( if (!objFifoSize(createOp)) return; - auto fifo = llvm::cast(createOp.getElemType()); - auto elemType = llvm::cast(fifo.getElementType()); + MemRefType fifoType = createOp.getElemType(); // if this objectFifo is linked to another, check if the other's elements // have already been created (the elements that are created are those of @@ -852,14 +844,10 @@ void createBuffersAndLocks( // if distribute, fifoIn has bigger size if (isDistribute(*linkOp) && name(createOp) != name(fifoIn)) return; - auto fifoInType = llvm::cast( - getInputObjectFifos(*linkOp)[0].getElemType()), - fifoOutType = llvm::cast( - getOutputObjectFifos(*linkOp)[0].getElemType()); - auto elemInType = llvm::cast(fifoInType.getElementType()), - elemOutType = llvm::cast(fifoOutType.getElementType()); - int64_t inSize = elemInType.getNumElements(); - if (int64_t outSize = elemOutType.getNumElements(); inSize >= outSize) { + auto fifoInType = getInputObjectFifos(*linkOp)[0].getElemType(), + fifoOutType = getOutputObjectFifos(*linkOp)[0].getElemType(); + int64_t inSize = fifoInType.getNumElements(); + if (int64_t outSize = fifoOutType.getNumElements(); inSize >= outSize) { if (name(createOp) != name(fifoIn)) return; } else if (getOutputObjectFifos(*linkOp)[0] != createOp) return; @@ -888,10 +876,10 @@ void createBuffersAndLocks( // create as many locks as there are external buffers for (int ofElemIndex = 0; ofElemIndex < numElem; ofElemIndex++) { auto buff = builder.create( - builder.getUnknownLoc(), elemType, creationTile, + builder.getUnknownLoc(), fifoType, creationTile, builder.getStringAttr(name(createOp).str() + "_buff_" + std::to_string(ofElemIndex)), - /*address*/ nullptr, /*initial_value*/ nullptr, + /*address*/ nullptr, /*mem_bank*/ nullptr); buffers.push_back(buff); } @@ -1138,8 +1126,7 @@ struct AMDAIEObjectFifoStatefulTransformPass : mlir::OperationPass { auto symName = createOp.getName(); createOp->setAttr(SymbolTable::getSymbolAttrName(), builder.getStringAttr("__erase_" + symName)); - auto memrefType = llvm::cast(createOp.getElemType()) - .getElementType(); + auto memrefType = createOp.getElemType(); builder.create(builder.getUnknownLoc(), symName, builder.getStringAttr("public"), memrefType, nullptr, false, nullptr); @@ -1148,8 +1135,7 @@ struct AMDAIEObjectFifoStatefulTransformPass : mlir::OperationPass { // Remove old ops SetVector opsToErase; device.walk([&](Operation *op) { - if (isa(op)) opsToErase.insert(op); }); diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp index 85554418c..f9416d7bc 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp @@ -4,8 +4,8 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "Passes.h" #include "AIEXDialect.h" +#include "Passes.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" @@ -22,7 +22,8 @@ struct AMDAIEXOpRemoval : OpConversionPattern { using OpAdaptor = typename MyAIEXOp::Adaptor; ModuleOp &module; - AMDAIEXOpRemoval(MLIRContext *context, ModuleOp &m, PatternBenefit benefit = 1) + AMDAIEXOpRemoval(MLIRContext *context, ModuleOp &m, + PatternBenefit benefit = 1) : OpConversionPattern(context, benefit), module(m) {} LogicalResult matchAndRewrite( diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/IR/AMDAIEOps.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/IR/AMDAIEOps.cpp index dd812930c..1c6e4866e 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/IR/AMDAIEOps.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/IR/AMDAIEOps.cpp @@ -373,10 +373,10 @@ void LogicalObjectFifoFromMemrefOp::build( SmallVector tiles; tiles.reserve(tileLocations.size()); for (auto [column, row] : tileLocations) { - auto colIndex = b.create(b.getUnknownLoc(), column); - auto rowIndex = b.create(b.getUnknownLoc(), row); + auto getCol = b.create(b.getUnknownLoc(), column); + auto getRow = b.create(b.getUnknownLoc(), row); auto tileOp = - b.create(b.getUnknownLoc(), colIndex, rowIndex); + b.create(b.getUnknownLoc(), getCol, getRow); tiles.push_back(tileOp.getResult()); } // For deterministic order. diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.cpp index a9a1175e7..b48afaac1 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.cpp @@ -9,8 +9,8 @@ #include #include "XCLBinGen.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" -#include "aie/Dialect/AIEX/IR/AIEXDialect.h" +#include "aie/AIEDialect.h" +#include "aie/AIEXDialect.h" #include "aievec/AIEVecDialect.h" #include "aievec/Passes.h" #include "aievec/XLLVMDialect.h" diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.h b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.h index 2e1ae9d79..cb5ccbae8 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.h +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AIETarget.h @@ -9,6 +9,7 @@ #include +#include "aie/AIEDialect.h" #include "iree/compiler/Dialect/HAL/Target/TargetBackend.h" #include "iree/compiler/Dialect/HAL/Target/TargetDevice.h" #include "iree/compiler/Utils/OptionUtils.h" diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp index 249dbe7e4..735502b15 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "AMDAIETargets.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/AIEDialect.h" #include "aie/Passes.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Module.h" @@ -16,7 +16,10 @@ using namespace xilinx::AIE; std::string utohexstr(uint32_t u) { return "0x" + llvm::utohexstr(u); } +namespace {} // namespace + namespace mlir::iree_compiler::AMDAIE { + LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, int tileCol, int tileRow) { DenseMap tiles; @@ -27,7 +30,7 @@ LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, DeviceOp deviceOp = *(module.getOps().begin()); collectTiles(deviceOp, tiles); - ::collectBuffers(deviceOp, buffers); + collectBuffers(deviceOp, buffers); // _entry_point _main_init // _symbol _main _after _main_init @@ -43,8 +46,8 @@ LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, AMDAIEDeviceModel deviceModel = getDeviceModel(static_cast(deviceOp.getDevice())); for (auto tile : deviceOp.getOps()) - if (tile.colIndex() == tileCol && tile.rowIndex() == tileRow) { - TileLoc srcCoord = {tile.colIndex(), tile.rowIndex()}; + if (tile.getCol() == tileCol && tile.getRow() == tileRow) { + TileLoc srcCoord = {tile.getCol(), tile.getRow()}; std::string corefunc = std::string("core_") + std::to_string(tile.getCol()) + "_" + @@ -57,7 +60,7 @@ LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, << " // Don't put data in code memory\n"; int stacksize = 0; - if (auto core = tile.getCoreOp()) stacksize = core.getStackSize(); + if (auto core = getCoreOp(tile)) stacksize = core.getStackSize(); output << "_stack DM_stack " << utohexstr(deviceModel.getMemInternalBaseAddress()) << " " << utohexstr(stacksize) << " // stack for core\n"; @@ -78,21 +81,15 @@ LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, // remaining buffer) if (tiles.count(TileLoc(*tile))) { for (auto buf : buffers[tiles[TileLoc(*tile)]]) { - std::string bufName(buf.name().getValue()); - int bufferBaseAddr = getBufferBaseAddress(buf); - int numBytes = buf.getAllocationSize(); - if (buf.getInitialValue() && srcCoord == tile) { - output << "_overlay " << bufName << " " - << utohexstr(offset + bufferBaseAddr) << " // " - << numBytes << " bytes\n"; - } else { - output << "_symbol " << bufName << " " - << utohexstr(offset + bufferBaseAddr) << " " << numBytes - << '\n'; - output << "_extern " << bufName << "\n"; - output << "_reserved DMb " << utohexstr(offset + bufferBaseAddr) - << " " << numBytes << '\n'; - } + std::string bufName(name(buf).getValue()); + int bufferBaseAddr = buf.getAddress().value(); + int numBytes = getAllocationSize(buf); + output << "_symbol " << bufName << " " + << utohexstr(offset + bufferBaseAddr) << " " << numBytes + << '\n'; + output << "_extern " << bufName << "\n"; + output << "_reserved DMb " << utohexstr(offset + bufferBaseAddr) + << " " << numBytes << '\n'; output << "\n"; } } diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp index b8e7d3607..9e1bc792c 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp @@ -11,8 +11,8 @@ #include #include "AMDAIETargets.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" -#include "aie/Dialect/AIE/IR/AIEEnums.h" +#include "aie/AIEDialect.h" +#include "aie/AIEEnums.h" #include "iree-amd-aie/aie_runtime/iree_aie_configure.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/STLExtras.h" @@ -32,7 +32,6 @@ using namespace mlir; using xilinx::AIE::AMSelOp; using xilinx::AIE::BufferOp; using xilinx::AIE::CascadeDir; -using xilinx::AIE::ConfigureCascadeOp; using xilinx::AIE::ConnectOp; using xilinx::AIE::CoreOp; using xilinx::AIE::DeviceOp; @@ -40,17 +39,15 @@ using xilinx::AIE::DMABDOp; using xilinx::AIE::DMABDPACKETOp; using xilinx::AIE::DMAChannelDir; using xilinx::AIE::DMAStartOp; -using xilinx::AIE::Interconnect; +using xilinx::AIE::LockAction; using xilinx::AIE::LockOp; using xilinx::AIE::MasterSetOp; using xilinx::AIE::MemOp; using xilinx::AIE::MemTileDMAOp; using xilinx::AIE::PacketRuleOp; using xilinx::AIE::PacketRulesOp; -using xilinx::AIE::ShimDMAOp; using xilinx::AIE::ShimMuxOp; using xilinx::AIE::SwitchboxOp; -using xilinx::AIE::TileElement; using xilinx::AIE::TileOp; using xilinx::AIE::UseLockOp; using xilinx::AIE::WireBundle; @@ -136,13 +133,14 @@ LogicalResult configureLocksAndBd(Block &block, const TileLoc &tileLoc, case Lock::Action::Acquire: case Lock::Action::AcquireGreaterEqual: acqEn = op.getAcqEn(); - acqLockId = lock.getLockIDValue(); - acqValue = op.getLockValue(); - if (op.acquireGE()) acqValue.value() = -acqValue.value(); + acqLockId = lock.getLockID(); + acqValue = op.getValue().value_or(1); + if (op.getAction() == LockAction::AcquireGreaterEqual) + acqValue.value() = -acqValue.value(); break; case Lock::Action::Release: - relLockId = lock.getLockIDValue(); - relValue = op.getLockValue(); + relLockId = lock.getLockID(); + relValue = op.getValue().value_or(1); break; } } @@ -168,7 +166,7 @@ LogicalResult configureLocksAndBd(Block &block, const TileLoc &tileLoc, "expected only one dma_bd_packet"); auto packetOp = *maybePacketOps.begin(); packetType = packetOp.getPacketType(); - packetID = packetOp.getPacketID(); + packetID = packetOp.getPacketId(); } BufferOp bufferOp = cast(bdOp.getBuffer().getDefiningOp()); @@ -197,8 +195,8 @@ LogicalResult configureLocksAndBd(Block &block, const TileLoc &tileLoc, *bdOp.getNextBdId())} : std::nullopt, packetType, packetID, *bufferOp.getAddress(), - bdOp.getLenInBytes(), bdOp.getOffsetInBytes(), - bdOp.getBufferElementTypeWidthInBytes(), maybeDims, + getLenInBytes(bdOp), getOffsetInBytes(bdOp), + getBufferElementTypeWidthInBytes(bdOp), maybeDims, maybePadDims))) { return failure(); } @@ -211,7 +209,7 @@ LogicalResult addAieElfsToCDO(const AMDAIEDeviceModel &deviceModel, for (auto tileOp : device.getOps()) { TileLoc tileLoc{tileOp.getCol(), tileOp.getRow()}; if (deviceModel.isShimNOCorPLTile(tileLoc.col, tileLoc.row)) continue; - if (auto coreOp = tileOp.getCoreOp()) { + if (auto coreOp = getCoreOp(tileOp)) { std::string fileName; if (auto elfFile = coreOp.getElfFile()) fileName = *elfFile; @@ -234,17 +232,18 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, if (deviceModel.isShimTile(tileOp.getCol(), tileOp.getRow())) { continue; } - if (auto coreOp = tileOp.getCoreOp(); + if (auto coreOp = getCoreOp(tileOp); coreOp && failed(resetUnResetCore(deviceModel, tileLoc))) { return failure(); } } // Set locks with explicit initializers - WalkResult r = device.walk([&](LockOp lockOp) { + WalkResult r; + r = device.walk([&](LockOp lockOp) { if (lockOp.getLockID() && lockOp.getInit()) { - TileLoc tileLoc = {lockOp.getTileOp().getCol(), - lockOp.getTileOp().getRow()}; + TileOp t = xilinx::AIE::getTileOp(*lockOp.getOperation()); + TileLoc tileLoc = {t.getCol(), t.getRow()}; Lock lock{tileLoc, static_cast(*lockOp.getLockID()), static_cast(*lockOp.getInit())}; if (failed(initializeLock(deviceModel, lock))) @@ -254,23 +253,23 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, }); if (r.wasInterrupted()) return failure(); - auto memOps = llvm::to_vector_of(device.getOps()); + auto memOps = llvm::to_vector_of(device.getOps()); llvm::append_range(memOps, device.getOps()); - llvm::append_range(memOps, device.getOps()); - for (TileElement memOp : memOps) { - TileLoc tileLoc = {memOp.getTileID().col, memOp.getTileID().row}; + for (Operation *memOp : memOps) { + TileOp t = xilinx::AIE::getTileOp(*memOp); + TileLoc tileLoc = {t.getCol(), t.getRow()}; if (deviceModel.isShimNOCorPLTile(tileLoc.col, tileLoc.row)) { continue; } // handle DMA ops separately - for (Block &block : memOp.getOperation()->getRegion(0)) { + for (Block &block : memOp->getRegion(0)) { if (block.getOps().empty()) continue; if (failed(configureLocksAndBd(block, tileLoc, deviceModel))) return failure(); } - for (Block &block : memOp.getOperation()->getRegion(0)) { + for (Block &block : memOp->getRegion(0)) { for (auto op : block.getOps()) { DMABDOp bd = *op.getDest()->getOps().begin(); int chNum = op.getChannelIndex(); @@ -286,7 +285,8 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, // StreamSwitch (switchbox) configuration for (auto switchboxOp : device.getOps()) { - SwitchBox swb = {switchboxOp.colIndex(), switchboxOp.rowIndex()}; + TileOp t = xilinx::AIE::getTileOp(*switchboxOp.getOperation()); + SwitchBox swb = {t.getCol(), t.getRow()}; std::vector connects; for (auto connectOp : switchboxOp.getOps()) { connects.emplace_back(Port{toAMDAIEStrmT(connectOp.getSourceBundle()), @@ -324,9 +324,9 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, deviceModel, swb, toAMDAIEStrmT(packetRulesOp.getSourceBundle()), packetRulesOp.getSourceChannel(), - AMSel{static_cast(amselOp.arbiterIndex()), - static_cast(amselOp.getMselValue())}, - packetRuleOp.valueInt(), packetRuleOp.maskInt(), slot))) + AMSel{static_cast(amselOp.getArbiterID()), + static_cast(amselOp.getMsel())}, + packetRuleOp.getValue(), packetRuleOp.getMask(), slot))) return failure(); slot++; } @@ -334,7 +334,8 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, } for (auto muxOp : device.getOps()) { - SwitchBox swb = {muxOp.getTileOp().getCol(), muxOp.getTileOp().getRow()}; + TileOp t = xilinx::AIE::getTileOp(*muxOp.getOperation()); + SwitchBox swb = {t.getCol(), t.getRow()}; std::vector connects; for (auto connectOp : muxOp.getOps()) { connects.emplace_back(Port{toAMDAIEStrmT(connectOp.getSourceBundle()), @@ -348,15 +349,6 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, } } - // Cascade configuration - for (auto configOp : device.getOps()) { - TileOp tile = cast(configOp.getTile().getDefiningOp()); - TileLoc tileLoc = {tile.getCol(), tile.getCol()}; - Cascade casc = {tileLoc, toDir(configOp.getInputDir()), - toDir(configOp.getOutputDir())}; - if (failed(configureCascade(deviceModel, casc))) return failure(); - } - return success(); } @@ -365,7 +357,7 @@ LogicalResult addCoreEnableToCDO(const AMDAIEDeviceModel &deviceModel, // Start execution of all the cores. for (auto tileOp : device.getOps()) { TileLoc tileLoc = {tileOp.getCol(), tileOp.getRow()}; - if (auto coreOp = tileOp.getCoreOp(); + if (auto coreOp = getCoreOp(tileOp); coreOp && failed(coreEnable(deviceModel, tileLoc))) return failure(); } diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp index 63c4a6f37..d770e81df 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp @@ -5,7 +5,7 @@ // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception #include "AMDAIETargets.h" -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/AIEDialect.h" using namespace mlir; using namespace xilinx; @@ -15,9 +15,9 @@ using namespace xilinx::AIE; // with the given offset. The offset is different depending on where the buffers // are accessed from. static void writeLDScriptMap(raw_ostream &output, BufferOp buf, int offset) { - std::string bufName(buf.name().getValue()); - int bufferBaseAddr = getBufferBaseAddress(buf); - int numBytes = buf.getAllocationSize(); + std::string bufName(name(buf).getValue()); + int bufferBaseAddr = buf.getAddress().value(); + int numBytes = getAllocationSize(buf); output << ". = 0x" << llvm::utohexstr(offset + bufferBaseAddr) << ";\n"; output << bufName << " = .;\n"; output << ". += 0x" << llvm::utohexstr(numBytes) << ";\n"; @@ -65,15 +65,15 @@ LogicalResult mlir::iree_compiler::AMDAIE::AIETranslateToLdScript( AMDAIEDeviceModel deviceModel = getDeviceModel(static_cast(deviceOp.getDevice())); for (auto tile : deviceOp.getOps()) - if (tile.colIndex() == tileCol && tile.rowIndex() == tileRow) { - TileLoc srcCoord = {tile.colIndex(), tile.rowIndex()}; + if (tile.getCol() == tileCol && tile.getRow() == tileRow) { + TileLoc srcCoord = {tile.getCol(), tile.getRow()}; // Figure out how much memory we have left for random allocations - auto core = tile.getCoreOp(); + auto core = getCoreOp(tile); int max = core.getStackSize(); for (auto buf : buffers[tiles[srcCoord]]) { - int bufferBaseAddr = getBufferBaseAddress(buf); - int numBytes = buf.getAllocationSize(); + int bufferBaseAddr = buf.getAddress().value(); + int numBytes = getAllocationSize(buf); max = std::max(max, bufferBaseAddr + numBytes); } int origin = deviceModel.getMemInternalBaseAddress() + max; @@ -120,7 +120,7 @@ SECTIONS << ";\n"; output << "_sp_start_value_DM_stack = .;\n"; - if (auto core = tile.getCoreOp()) + if (auto core = getCoreOp(tile)) output << ". += 0x" << llvm::utohexstr(core.getStackSize()) << "; /* stack */\n"; else @@ -138,7 +138,7 @@ SECTIONS output << " .bss : { *(.bss) } > data\n"; output << " .bss.DMb.4 : { *(.bss.DMb.4) } > data\n"; output << "}\n"; - if (auto coreOp = tile.getCoreOp()) { + if (auto coreOp = getCoreOp(tile)) { output << "PROVIDE(main = core_" << tile.getCol() << "_" << tile.getRow() << ");\n"; } diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargets.h b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargets.h index f6a0c398e..5052fadd8 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargets.h +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargets.h @@ -7,7 +7,7 @@ #ifndef AIE_TARGETS_AIETARGETS_H #define AIE_TARGETS_AIETARGETS_H -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/AIEDialect.h" #include "aie/Passes.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/Support/raw_ostream.h" @@ -15,9 +15,6 @@ #include "mlir/Support/LogicalResult.h" namespace mlir::iree_compiler::AMDAIE { -mlir::LogicalResult AIETranslateToNPU(mlir::ModuleOp module, - llvm::raw_ostream &output); - std::vector AIETranslateToNPU(mlir::ModuleOp); mlir::LogicalResult AIETranslateToLdScript(mlir::ModuleOp module, @@ -32,26 +29,6 @@ mlir::LogicalResult AIETranslateToCDODirect( mlir::ModuleOp m, llvm::StringRef workDirPath, bool bigEndian = false, bool emitUnified = false, bool cdoDebug = false, bool aieSim = false, bool enableCores = true); - -inline void collectTiles( - xilinx::AIE::DeviceOp &device, - DenseMap &tiles) { - for (auto tile : device.getOps()) { - int colIndex = tile.colIndex(); - int rowIndex = tile.rowIndex(); - tiles[{colIndex, rowIndex}] = tile; - } -} - -inline void collectBuffers( - xilinx::AIE::DeviceOp &device, - DenseMap> &buffers) { - for (xilinx::AIE::BufferOp buffer : device.getOps()) { - Operation *tileOp = buffer.getTile().getDefiningOp(); - buffers[tileOp].push_back(buffer); - } -} - } // namespace mlir::iree_compiler::AMDAIE #endif diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/XCLBinGen.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/XCLBinGen.cpp index 9b5b3f317..18d4c3cfe 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/XCLBinGen.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/XCLBinGen.cpp @@ -14,7 +14,6 @@ #include #include "AMDAIETargets.h" -#include "aie/Targets/AIETargets.h" #include "aievec/Passes.h" #include "iree-amd-aie/Transforms/Passes.h" #include "iree/compiler/Utils/ToolUtils.h" @@ -142,21 +141,17 @@ static FailureOr findAMDAIETool(std::string toolName, Path toolBinExe = ""; if (!amdAIEInstallDir.empty()) { toolBinExe = amdAIEInstallDir / toolName; - if (llvm::sys::fs::exists(toolBinExe.native())) - return toolBinExe; + if (llvm::sys::fs::exists(toolBinExe.native())) return toolBinExe; toolBinExe = amdAIEInstallDir / "bin" / toolName; - if (llvm::sys::fs::exists(toolBinExe.native())) - return toolBinExe; + if (llvm::sys::fs::exists(toolBinExe.native())) return toolBinExe; toolBinExe = amdAIEInstallDir / "tools" / toolName; - if (llvm::sys::fs::exists(toolBinExe.native())) - return toolBinExe; + if (llvm::sys::fs::exists(toolBinExe.native())) return toolBinExe; } toolBinExe = mlir::iree_compiler::findTool(toolName); - if (llvm::sys::fs::exists(toolBinExe.native())) - return toolBinExe; + if (llvm::sys::fs::exists(toolBinExe.native())) return toolBinExe; llvm::errs() << "Could not find " << toolName << ". Check your --iree-amd-aie-install-dir flag"; @@ -321,7 +316,8 @@ static std::optional runTool( stats.TotalTime) .count(); std::string exitStatusStr = result == 0 ? "Succeeded" : "Failed"; - llvm::outs() << "\n" << exitStatusStr << " in totalTime " << totalTime + llvm::outs() << "\n" + << exitStatusStr << " in totalTime " << totalTime << " [s]. Exit code=" << result << "\n"; llvm::outs() << outputFromFile << "\n"; } @@ -468,9 +464,9 @@ static LogicalResult generateCoreElfFiles( std::string errorMessage; for (auto tileOp : tileOps) { - int col = tileOp.colIndex(); - int row = tileOp.rowIndex(); - auto coreOp = tileOp.getCoreOp(); + int col = tileOp.getCol(); + int row = tileOp.getRow(); + auto coreOp = getCoreOp(tileOp); if (!coreOp) continue; std::string elfFileName; diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEConvertCoreForallToFor.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEConvertCoreForallToFor.cpp index 4f985efce..8e3ec6093 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEConvertCoreForallToFor.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEConvertCoreForallToFor.cpp @@ -13,7 +13,7 @@ // //===----------------------------------------------------------------------===// -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/AIEDialect.h" #include "iree-amd-aie/Transforms/Passes.h" #include "mlir/Dialect/SCF/IR/SCF.h" #include "mlir/Dialect/SCF/Transforms/Transforms.h" diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp index 9adfec4a5..5350f05b4 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp @@ -4,7 +4,7 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/AIEDialect.h" #include "iree-amd-aie/IR/AMDAIEOps.h" #include "iree-amd-aie/Transforms/AMDAIEDmaUtils.h" #include "iree-amd-aie/Transforms/Passes.h" @@ -31,14 +31,6 @@ namespace { // Utilities //===----------------------------------------------------------------------===// -/// Comparator for a pair of `amdaie.dma_cpy_nd` on the first tile operation's -/// column index. -bool dmaColComparator( - std::pair> &a, - std::pair> &b) { - return TileOp::tileColumnComparator(a.second[0], b.second[0]); -}; - /// Utility to use tuple coordinates as key of a `DenseMap`. struct LocationMapInfo { static SmallVector> getEmptyKey() { @@ -679,12 +671,12 @@ LogicalResult assignLocalAieTiles(ModuleOp moduleOp) { tiles.reserve(tileLocations.size()); rewriter.setInsertionPoint(logicalObjectFifo); for (auto [column, row] : tileLocations) { - auto colIndex = rewriter.create( + auto getCol = rewriter.create( rewriter.getUnknownLoc(), column); - auto rowIndex = rewriter.create( + auto getRow = rewriter.create( rewriter.getUnknownLoc(), row); auto tileOp = rewriter.create( - rewriter.getUnknownLoc(), colIndex, rowIndex); + rewriter.getUnknownLoc(), getCol, getRow); tiles.push_back(tileOp.getResult()); } // Sort for deterministic output IR. diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp index d6f26d522..9a175c4a7 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp @@ -13,8 +13,8 @@ #include -#include "aie/Dialect/AIE/IR/AIEDialect.h" -#include "aie/Dialect/AIEX/IR/AIEXDialect.h" +#include "aie/AIEDialect.h" +#include "aie/AIEXDialect.h" #include "iree-amd-aie/IR/AMDAIEDialect.h" #include "iree-amd-aie/IR/AMDAIEOps.h" #include "iree-amd-aie/Transforms/AMDAIEUtils.h" @@ -128,12 +128,11 @@ AIE::ObjectFifoCreateOp createObjectFifo(IRRewriter &rewriter, : MemRefType::get({targetSize}, dstType.getElementType(), MemRefLayoutAttrInterface{}, rewriter.getI64IntegerAttr(1)); - AIE::AIEObjectFifoType dtype = AIE::AIEObjectFifoType::get(memrefType); auto depthInBytes = srcType.getElementTypeBitWidth() / 8; auto fifo = rewriter.create( rewriter.getUnknownLoc(), symName, srcTile, dstTiles, - rewriter.getIntegerAttr(rewriter.getI32Type(), depthInBytes), dtype, - sourceDims, targetDims); + rewriter.getIntegerAttr(rewriter.getI32Type(), depthInBytes), + llvm::cast(memrefType), sourceDims, targetDims); return fifo; } @@ -202,11 +201,9 @@ LogicalResult acquireOpToAIE(IRRewriter &rewriter, return acquireOp.emitError() << "input isn't mapped to an `aie.objectifo` operation"; } - AIE::AIEObjectFifoType ofTy = - cast(objFifo.getElemType()); - MemRefType elementType = MemRefType::Builder(ofTy.getElementType()) + MemRefType elementType = MemRefType::Builder(objFifo.getElemType()) .setMemorySpace(rewriter.getI64IntegerAttr(1)); - auto subviewType = AIE::AIEObjectFifoSubviewType::get(elementType); + auto subviewType = elementType; AIE::ObjectFifoPort port = acquireOp.getPort() == LogicalObjectFifoPort::Produce ? AIE::ObjectFifoPort::Produce diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc index 0a01481a8..ee2d29f88 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc @@ -550,6 +550,7 @@ struct AMDAIEDeviceModel getDeviceModel(AMDAIEDevice device) { std::string to_string(const int &value) { return std::to_string(value); } std::string to_string(const uint32_t &value) { return std::to_string(value); } std::string to_string(const uint64_t &value) { return std::to_string(value); } +std::string to_string(const size_t &value) { return std::to_string(value); } std::string to_string(const StrmSwPortType &value) { switch (value) { diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h index 01b9403b5..8814bba25 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h @@ -316,11 +316,11 @@ bool isNPUDevice(mlir::iree_compiler::AMDAIE::AMDAIEDevice d); /// ================== stringification utils ============================= /// ====================================================================== -std::string to_string(const int& value); -std::string to_string(const uint32_t& value); -std::string to_string(const uint64_t& value); - #define TO_STRINGS(_) \ + _(int) \ + _(uint32_t) \ + _(uint64_t) \ + _(size_t) \ _(AMDAIEDmaProp) \ _(AMDAIETileType) \ _(AieRC) \ @@ -410,16 +410,6 @@ static_assert(XAIE_OK == 0); to_string(r)); \ } while (0) -#define TRY_XAIE_API_EMIT_ERROR(OP, API, ...) \ - do { \ - LLVM_DEBUG(llvm::dbgs() << "XAIE API: " << #API << " with args: "); \ - LLVM_DEBUG(SHOW_ARGS(llvm::dbgs(), __VA_ARGS__)); \ - LLVM_DEBUG(llvm::dbgs() << "\n"); \ - LLVM_DEBUG(llvm::dbgs().flush()); \ - if (auto r = API(__VA_ARGS__)) \ - return OP.emitOpError() << #API " failed with " << r; \ - } while (0) - #define TRY_XAIE_API_LOGICAL_RESULT(API, ...) \ do { \ LLVM_DEBUG(llvm::dbgs() << "XAIE API: " << #API << " with args: "); \ From fd2e3aed530471c5d40d773a44efe4ce8b11d0ef Mon Sep 17 00:00:00 2001 From: max Date: Tue, 6 Aug 2024 00:09:12 -0500 Subject: [PATCH 07/12] patch air --- .../plugins/target/AMD-AIE/aie/AIEAttrs.td | 38 ----- .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 134 ++++++++++++++++++ .../plugins/target/AMD-AIE/aie/AIEDialect.h | 69 +++++---- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 113 ++++++++++----- .../plugins/target/AMD-AIE/aie/AIETypes.td | 27 ++++ compiler/plugins/target/AMD-AIE/aie/AIEX.td | 1 + .../AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp | 111 ++++----------- .../aie/AMDAIEObjectFifoStatefulTransform.cpp | 48 ++++--- .../plugins/target/AMD-AIE/aie/CMakeLists.txt | 13 ++ .../plugins/target/AMD-AIE/air/CMakeLists.txt | 53 +++++++ .../Target/AMDAIETargetCDODirect.cpp | 71 ++-------- .../Transforms/AMDAIELowerToAIE.cpp | 11 +- .../iree-amd-aie/aie_runtime/AMDAIEEnums.td | 20 +++ .../iree-amd-aie/aie_runtime/CMakeLists.txt | 34 ++--- .../aie_runtime/iree_aie_router.h | 3 +- .../aie_runtime/iree_aie_runtime.cc | 10 +- .../aie_runtime/iree_aie_runtime.h | 63 ++++---- .../aie_runtime/test/CMakeLists.txt | 28 ++-- .../aie_runtime/test/DeviceModelTest.cpp | 2 +- .../aie_runtime/test/cdo/aie_cdo_gen_test.cxx | 5 +- 20 files changed, 515 insertions(+), 339 deletions(-) create mode 100644 compiler/plugins/target/AMD-AIE/aie/AIETypes.td diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td index e0858d244..225545075 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td @@ -20,35 +20,6 @@ include "mlir/IR/EnumAttr.td" // AIE attributes. //===----------------------------------------------------------------------===// -def CoreWire: I32EnumAttrCase<"Core", 0>; -def DMAWire: I32EnumAttrCase<"DMA", 1>; -def FIFOWire: I32EnumAttrCase<"FIFO", 2>; -def SouthWire: I32EnumAttrCase<"South", 3>; -def WestWire: I32EnumAttrCase<"West", 4>; -def NorthWire: I32EnumAttrCase<"North", 5>; -def EastWire: I32EnumAttrCase<"East", 6>; -def PLIOWire: I32EnumAttrCase<"PLIO", 7>; -def NOCWire: I32EnumAttrCase<"NOC", 8>; -def TraceWire: I32EnumAttrCase<"Trace", 9>; -def ControlWire: I32EnumAttrCase<"Ctrl", 10>; - -def WireBundle: I32EnumAttr<"WireBundle", "Bundle of wires", - [ - CoreWire, DMAWire, FIFOWire, SouthWire, WestWire, NorthWire, - EastWire, PLIOWire, NOCWire, TraceWire, ControlWire - ]> { - - let cppNamespace = "xilinx::AIE"; -} - -def CascadeDir: I32EnumAttr<"CascadeDir", "Directions for cascade", - [ - SouthWire, WestWire, NorthWire, EastWire - ]> { - - let cppNamespace = "xilinx::AIE"; -} - def LockAction: I32EnumAttr<"LockAction", "lock acquire/release", [ I32EnumAttrCase<"Acquire", 0>, @@ -102,15 +73,6 @@ def ObjectFifoPort: I32EnumAttr<"ObjectFifoPort", let cppNamespace = "xilinx::AIE"; } -def DMAChannelDir: I32EnumAttr<"DMAChannelDir", - "DMA Channel direction", - [ - I32EnumAttrCase<"S2MM", 0>, - I32EnumAttrCase<"MM2S", 1> - ]> { - let cppNamespace = "xilinx::AIE"; -} - def BDDimLayoutAttr : AttrDef { let mnemonic = "bd_dim_layout"; let summary = [{ diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index 2fd513843..228c2e41e 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -28,7 +28,141 @@ using namespace xilinx::AIE; #include "aie/AIEDialect.cpp.inc" namespace xilinx::AIE { + +namespace detail { +struct AIEObjectFifoTypeStorage : TypeStorage { + using KeyTy = MemRefType; + AIEObjectFifoTypeStorage(MemRefType elementType) : elementType(elementType) {} + bool operator==(const KeyTy &key) const { return key == KeyTy(elementType); } + static AIEObjectFifoTypeStorage *construct(TypeStorageAllocator &allocator, + const KeyTy &key) { + return new (allocator.allocate()) + AIEObjectFifoTypeStorage(key); + } + + MemRefType elementType; +}; +} // namespace detail + +AIEObjectFifoType AIEObjectFifoType::get(MemRefType elementType) { + MLIRContext *ctx = elementType.getContext(); + return Base::get(ctx, elementType); +} + +mlir::MemRefType AIEObjectFifoType::getElementType() { + // 'getImpl' returns a pointer to the internal storage instance. + return getImpl()->elementType; +} + +namespace detail { +struct AIEObjectFifoSubviewTypeStorage : TypeStorage { + using KeyTy = MemRefType; + AIEObjectFifoSubviewTypeStorage(MemRefType elementType) + : elementType(elementType) {} + bool operator==(const KeyTy &key) const { return key == elementType; } + static AIEObjectFifoSubviewTypeStorage *construct( + TypeStorageAllocator &allocator, const KeyTy &key) { + return new (allocator.allocate()) + AIEObjectFifoSubviewTypeStorage(key); + } + + MemRefType elementType; +}; +} // namespace detail + +AIEObjectFifoSubviewType AIEObjectFifoSubviewType::get(MemRefType elementType) { + MLIRContext *ctx = elementType.getContext(); + return Base::get(ctx, elementType); +} +MemRefType AIEObjectFifoSubviewType::getElementType() { + return getImpl()->elementType; +} + +static OptionalParseResult aieTypeParser(DialectAsmParser &parser, + StringRef name, Type &result) { + if (name == "objectfifo") { + MemRefType elementType; + SMLoc typeLoc = parser.getCurrentLocation(); + if (parser.parseLess() || parser.parseType(elementType) || + parser.parseGreater()) + return failure(); + + // Check that the type is a MemRef type. + if (!llvm::isa(elementType)) { + parser.emitError(typeLoc, + "element type for an objectFifo must be " + "a MemRefType, got: ") + << elementType; + return failure(); + } + + return result = AIEObjectFifoType::get(elementType), success(); + } + + if (name == "objectfifosubview") { + if (parser.parseLess()) return failure(); + + // Parse the element type of the struct. + MemRefType elementType; + // Parse the current element type. + SMLoc typeLoc = parser.getCurrentLocation(); + if (parser.parseType(elementType)) return failure(); + + // Check that the type is a MemRefType. + if (!llvm::isa(elementType)) { + parser.emitError(typeLoc, + "element type for a subview must be " + "a MemRefType, got: ") + << elementType; + return failure(); + } + + // Parse: `>` + if (parser.parseGreater()) return failure(); + + return result = AIEObjectFifoSubviewType::get(elementType), success(); + } + + return {}; +} + +static ParseResult parse(Type &result, StringRef name, + DialectAsmParser &parser) { + if (OptionalParseResult parseResult = aieTypeParser(parser, name, result); + parseResult.has_value()) + return parseResult.value(); + + parser.emitError(parser.getNameLoc(), "unknown AIE dialect type: \"") + << name << "\""; + return failure(); +} + +/// Parse an instance of a type registered to the AIE dialect. +Type AIEDialect::parseType(DialectAsmParser &parser) const { + StringRef name; + Type result; + if (parser.parseKeyword(&name) || parse(result, name, parser)) return {}; + return result; +} + +/// Print an instance of a type registered to the AIE dialect. +void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { + if (llvm::isa(type)) { + auto objectFifoType = llvm::cast(type); + printer << "objectfifo<"; + printer << objectFifoType.getElementType(); + printer << '>'; + + } else if (llvm::isa(type)) { + auto subviewType = llvm::cast(type); + printer << "objectfifosubview<"; + printer << subviewType.getElementType(); + printer << '>'; + } +} + void AIEDialect::initialize() { + addTypes(); addAttributes< #define GET_ATTRDEF_LIST #include "aie/AIEAttrs.cpp.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index 73ffb5601..7da7cc48e 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -12,6 +12,7 @@ #define MLIR_AIE_DIALECT_H #include "AIEEnums.h" +#include "iree-amd-aie/aie_runtime/iree_aie_router.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "mlir/Dialect/Arith/IR/Arith.h" #include "mlir/Dialect/ControlFlow/IR/ControlFlow.h" @@ -53,6 +54,34 @@ struct MyOffsetSizeAndStrideOpInterfaceTrait } }; +namespace detail { +struct AIEObjectFifoTypeStorage; +} + +class AIEObjectFifoType + : public mlir::Type::TypeBase { + public: + using Base::Base; + static AIEObjectFifoType get(mlir::MemRefType elementType); + static constexpr llvm::StringLiteral name = "objectfifo"; + mlir::MemRefType getElementType(); +}; + +namespace detail { +struct AIEObjectFifoSubviewTypeStorage; +} + +class AIEObjectFifoSubviewType + : public mlir::Type::TypeBase { + public: + using Base::Base; + static AIEObjectFifoSubviewType get(mlir::MemRefType elementType); + static constexpr llvm::StringLiteral name = "objectfifosubview"; + mlir::MemRefType getElementType(); +}; + /// Include the generated interface declarations. #include "aie/AIEInterfaces.h.inc" @@ -61,6 +90,12 @@ struct MyOffsetSizeAndStrideOpInterface template struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait {}; }; + +using DMAChannelDir = mlir::iree_compiler::AMDAIE::DMAChannelDir; +using Port = mlir::iree_compiler::AMDAIE::Port; +using WireBundle = mlir::iree_compiler::AMDAIE::StrmSwPortType; +using DMAChannelDirAttr = mlir::iree_compiler::AMDAIE::DMAChannelDirAttr; +// using DMAChannel = mlir::iree_compiler::AMDAIE::DMAChannel; } // namespace xilinx::AIE // Include dialect declarations such as parseAttributes, parseType @@ -192,6 +227,10 @@ CoreOp getCoreOp(TileOp &op) { return nullptr; } +MemOp TileOp::getMemOp() { return ::xilinx::AIE::getMemOp(*this); } + +CoreOp TileOp::getCoreOp() { return ::xilinx::AIE::getCoreOp(*this); } + void collectBuffers(DeviceOp &device, llvm::DenseMap> &buffers) { @@ -231,41 +270,15 @@ mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( uint32_t getAddressGenGranularity() { return 32; }; -typedef struct DMAChannel { +struct DMAChannel { DMAChannelDir direction; int channel; bool operator==(const DMAChannel &rhs) const { return std::tie(direction, channel) == std::tie(rhs.direction, rhs.channel); } -} DMAChannel; +}; } // namespace xilinx::AIE -namespace llvm { -template <> -struct DenseMapInfo { - using FirstInfo = DenseMapInfo; - using SecondInfo = DenseMapInfo; - - static xilinx::AIE::DMAChannel getEmptyKey() { - return {FirstInfo::getEmptyKey(), SecondInfo::getEmptyKey()}; - } - - static xilinx::AIE::DMAChannel getTombstoneKey() { - return {FirstInfo::getTombstoneKey(), SecondInfo::getTombstoneKey()}; - } - - static unsigned getHashValue(const xilinx::AIE::DMAChannel &d) { - return detail::combineHashValue(FirstInfo::getHashValue(d.direction), - SecondInfo::getHashValue(d.channel)); - } - - static bool isEqual(const xilinx::AIE::DMAChannel &lhs, - const xilinx::AIE::DMAChannel &rhs) { - return lhs == rhs; - } -}; -} // namespace llvm - #endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index 6a7ba40d6..9c49d0797 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -14,6 +14,8 @@ include "AIE.td" include "AIEAttrs.td" include "AIEInterfaces.td" +include "AIETypes.td" +include "iree-amd-aie/aie_runtime/AMDAIEEnums.td" include "mlir/IR/CommonAttrConstraints.td" include "mlir/IR/SymbolInterfaces.td" @@ -35,7 +37,11 @@ def AIE_DeviceOp: AIE_Op<"device", [ let assemblyFormat = [{ `(` $device `)` regions attr-dict }]; - let hasVerifier = 1; + + // mlir-air legacy + let extraClassDeclaration = [{ + mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getTargetModel(); + }]; } def AIE_TileOp: AIE_Op<"tile", [ @@ -52,7 +58,17 @@ def AIE_TileOp: AIE_Op<"tile", [ `(` $col `,` $row `)` attr-dict }]; - let hasVerifier = 1; + // mlir-air legacy + let extraClassDeclaration = [{ + int colIndex() { return getCol(); } + int rowIndex() { return getRow(); } + bool isShimTile() { return getRow() == 0; } + CoreOp getCoreOp(); + bool isMemTile(); + MemOp getMemOp(); + size_t getNumSourceConnections(mlir::iree_compiler::AMDAIE::StrmSwPortType w); + size_t getNumDestConnections(mlir::iree_compiler::AMDAIE::StrmSwPortType w); + }]; } def AIE_EndOp: AIE_Op<"end", [Terminator]> { @@ -69,7 +85,6 @@ def AIE_SwitchboxOp: AIE_Op<"switchbox", [ let summary = "Declare a switch"; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; - let hasVerifier = 1; } def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ @@ -80,7 +95,6 @@ def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ let summary = "Declare a switch in the PL shim"; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $col `)` regions attr-dict }]; - let hasVerifier = 1; } def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ @@ -93,7 +107,6 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ let summary = "Declare a switch in the PL shim"; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; - let hasVerifier = 1; } def AIE_CoreOp: AIE_Op<"core", [ @@ -108,20 +121,23 @@ def AIE_CoreOp: AIE_Op<"core", [ let summary = "Declare a core module"; let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; - let hasVerifier = 1; let builders = [ OpBuilder<(ins "mlir::Value":$tile), [{ build($_builder, $_state, $_builder.getIndexType(), tile); }]> ]; + // mlir-air legacy + let extraClassDeclaration = [{ + TileOp getTileOp(); + }]; } def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { let arguments = ( - ins WireBundle:$source_bundle, + ins StrmSwPortType:$source_bundle, ConfinedAttr]>:$source_channel, - WireBundle:$dest_bundle, + StrmSwPortType:$dest_bundle, ConfinedAttr]>:$dest_channel ); let summary = "A circuit-switched connection inside a switchbox"; @@ -133,10 +149,10 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> def AIE_FlowOp: AIE_Op<"flow", []> { let arguments = ( ins Index:$source, - WireBundle:$source_bundle, + StrmSwPortType:$source_bundle, ConfinedAttr]>:$source_channel, Index:$dest, - WireBundle:$dest_bundle, + StrmSwPortType:$dest_bundle, ConfinedAttr]>:$dest_channel ); let summary = "A logical circuit-switched connection between cores"; @@ -173,7 +189,7 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let arguments = ( - ins WireBundle:$dest_bundle, + ins StrmSwPortType:$dest_bundle, ConfinedAttr]>:$dest_channel, Variadic:$amsels ); @@ -185,13 +201,12 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"EndOp">]> { let arguments = ( - ins WireBundle:$source_bundle, + ins StrmSwPortType:$source_bundle, ConfinedAttr]>:$source_channel ); let regions = (region AnyRegion:$rules); let summary = "Packet switched routing rules"; let assemblyFormat = [{ `(` $source_bundle `:` $source_channel `)` regions attr-dict }]; - let hasVerifier = 1; } def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { @@ -216,31 +231,44 @@ def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndO let regions = (region AnyRegion:$ports); let assemblyFormat = [{ `(` $ID `)` regions attr-dict }]; - let hasVerifier = 1; + // mlir-air legacy + let extraClassDeclaration = [{ + int IDInt() { return getID(); } + }]; } def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { let arguments = ( ins Index:$tile, - WireBundle:$bundle, + StrmSwPortType:$bundle, ConfinedAttr]>:$channel ); let summary = "A sourceport"; let assemblyFormat = [{ `<` $tile `,` $bundle `:` $channel `>` attr-dict }]; + + // mlir-air legacy + let extraClassDeclaration = [{ + Port port() { return {getBundle(), getChannel()}; } + }]; } def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { let arguments = ( ins Index:$tile, - WireBundle:$bundle, + StrmSwPortType:$bundle, ConfinedAttr]>:$channel ); let summary = "A destination port"; let assemblyFormat = [{ `<` $tile `,` $bundle `:` $channel `>` attr-dict }]; + + // mlir-air legacy + let extraClassDeclaration = [{ + Port port() { return {getBundle(), getChannel()}; } + }]; } def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { @@ -273,13 +301,11 @@ def AIE_DMABDOp: AIE_Op<"dma_bd", [ OptionalAttr:$next_bd_id ); - let hasVerifier = 1; let assemblyFormat = [{ `(` $buffer `:` type($buffer) (`,` $offset^)? (`,` $len^)? (`,` $dimensions^)? (`,` $pad_dimensions^)? (`,` `pad_value` `=` $pad_value^)? `)` attr-dict }]; - let hasVerifier = 1; let builders = [ OpBuilder<(ins "mlir::Value":$buffer, "int":$offset, "int":$len), [{ $_state.addOperands(buffer); @@ -336,7 +362,6 @@ def AIE_MemOp: AIE_Op<"mem", [ let arguments = (ins Index:$tile); let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; - let hasVerifier = 1; } def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ @@ -346,7 +371,6 @@ def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ let arguments = (ins Index:$tile); let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; - let hasVerifier = 1; } def AIE_NextBDOp: AIE_Op<"next_bd", [ @@ -384,7 +408,13 @@ def AIE_LockOp: AIE_Op<"lock", [ ); }]> ]; - let hasVerifier = 1; + // mlir-air legacy + let extraClassDeclaration = [{ + int getLockIDValue() { + assert(getLockID().has_value() && "Lock has no ID value"); + return getLockID().value(); + } + }]; } def AIE_UseLockOp: AIE_Op<"use_lock", []> { @@ -401,7 +431,6 @@ def AIE_UseLockOp: AIE_Op<"use_lock", []> { `(` $lock `,` $action (`,` $value^)? (`,` $blocking^)? `)` attr-dict }]; - let hasVerifier = 1; let builders = [ OpBuilder<(ins "mlir::Value":$lock, "xilinx::AIE::LockAction":$action, @@ -424,7 +453,10 @@ def AIE_BufferOp: AIE_Op<"buffer", []>, Results<(outs AnyMemRef)> { let assemblyFormat = [{ `(` $tile `)` attr-dict `:` type($buffer) }]; - let hasVerifier = 1; + // mlir-air legacy + let extraClassDeclaration = [{ + TileOp getTileOp(); + }]; } def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp">]> { @@ -452,7 +484,7 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] Index:$producerTile, Variadic:$consumerTiles, AnyAttrOf<[ConfinedAttr]>, ArrayAttr]>:$elemNumber, - TypeAttrOf:$elemType, + TypeAttrOf:$elemType, BDDimLayoutArrayAttr:$dimensionsToStream, BDDimLayoutArrayArrayAttr:$dimensionsFromStreamPerConsumer, DefaultValuedAttr:$via_DMA, @@ -471,8 +503,6 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] `)` attr-dict `:` $elemType }]; - let hasVerifier = 1; - let builders = [ OpBuilder<(ins "mlir::StringAttr":$sym_name, "mlir::Value":$producerTile, "mlir::ValueRange":$consumerTiles, "mlir::Attribute":$elemNumber, "mlir::Type":$elem_type, @@ -489,6 +519,12 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] odsBuilder.getAttr(dimensionsFromStreamPerConsumer)); }]> ]; + + let extraClassDeclaration = [{ + mlir::StringAttr name() { + return ::xilinx::AIE::name(*this); + } + }]; } def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { @@ -504,7 +540,6 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { $fifoIns `->` $fifoOuts `(` `)` attr-dict }]; - let hasVerifier = 1; } def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { @@ -515,13 +550,12 @@ def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { ConfinedAttr]>:$size ); - let results = (outs AnyMemRef:$subview); + let results = (outs AIE_ObjectFifoSubviewType:$subview); let assemblyFormat = [{ attr-dict $objFifo_name `(` $port `,` $size `)` `:` type($subview) }]; - let hasVerifier = 1; } def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { @@ -536,17 +570,15 @@ def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { attr-dict $objFifo_name `(` $port `,` $size `)` }]; - let hasVerifier = 1; } def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { let summary = "ObjectFifoSubview type accessor method"; let arguments = ( - ins AnyMemRef:$subview, + ins AIE_ObjectFifoSubviewType:$subview, ConfinedAttr]>:$index ); - let hasVerifier = 1; let results = (outs AnyMemRef:$output); @@ -570,4 +602,21 @@ def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ let assemblyFormat = [{ attr-dict `:` type($buffer) }]; } +def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ + DeclareOpInterfaceMethods + ]>, Results<(outs Index)> { + let arguments = ( + ins Index:$tile + ); + let summary = "Declare a DMA in the PL shim"; + let regions = (region AnyRegion:$body); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + }]; +} + + #endif // AIE_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td new file mode 100644 index 000000000..97ccf6a97 --- /dev/null +++ b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td @@ -0,0 +1,27 @@ +//===- AIETypes.td -----------------------------------------*- tablegen -*-===// +// +// 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 2019 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#ifndef AIE_TYPES +#define AIE_TYPES + +include "aie/Dialect/AIE/IR/AIE.td" +include "aie/Dialect/AIE/IR/AIEAttrs.td" + +include "mlir/IR/AttrTypeBase.td" + +def AIE_ObjectFifoType : + DialectType($_self)">, + "AIE objectFifo type">; + +def AIE_ObjectFifoSubviewType : + DialectType($_self)">, + "AIE ObjectFifoSubview type">; + +#endif // AIE_TYPES \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEX.td b/compiler/plugins/target/AMD-AIE/aie/AIEX.td index 91398a402..3ff90703b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEX.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEX.td @@ -13,6 +13,7 @@ include "AIEAttrs.td" include "AIEInterfaces.td" +include "iree-amd-aie/aie_runtime/AMDAIEEnums.td" include "mlir/IR/OpBase.td" include "mlir/IR/AttrTypeBase.td" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp index 7e74227ba..d531ec619 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIECreatePathFindFlows.cpp @@ -14,7 +14,6 @@ #include "iree-amd-aie/aie_runtime/iree_aie_router.h" #include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" #include "llvm/ADT/DenseMapInfo.h" -#include "llvm/Support/Debug.h" #include "llvm/Support/raw_os_ostream.h" #include "mlir/Pass/Pass.h" #include "mlir/Transforms/DialectConversion.h" @@ -45,60 +44,6 @@ using xilinx::AIE::TileOp; namespace mlir::iree_compiler::AMDAIE { -StrmSwPortType toStrmT(xilinx::AIE::WireBundle w) { - switch (w) { - case xilinx::AIE::WireBundle::Core: - return StrmSwPortType::CORE; - case xilinx::AIE::WireBundle::DMA: - return StrmSwPortType::DMA; - case xilinx::AIE::WireBundle::FIFO: - return StrmSwPortType::FIFO; - case xilinx::AIE::WireBundle::South: - return StrmSwPortType::SOUTH; - case xilinx::AIE::WireBundle::West: - return StrmSwPortType::WEST; - case xilinx::AIE::WireBundle::North: - return StrmSwPortType::NORTH; - case xilinx::AIE::WireBundle::East: - return StrmSwPortType::EAST; - case xilinx::AIE::WireBundle::NOC: - return StrmSwPortType::NOC; - case xilinx::AIE::WireBundle::Trace: - return StrmSwPortType::TRACE; - case xilinx::AIE::WireBundle::Ctrl: - return StrmSwPortType::CTRL; - default: - llvm::report_fatal_error("unhandled xilinx::AIE::WireBundle"); - } -} - -xilinx::AIE::WireBundle toWireB(StrmSwPortType w) { - switch (w) { - case StrmSwPortType::CORE: - return xilinx::AIE::WireBundle::Core; - case StrmSwPortType::DMA: - return xilinx::AIE::WireBundle::DMA; - case StrmSwPortType::FIFO: - return xilinx::AIE::WireBundle::FIFO; - case StrmSwPortType::SOUTH: - return xilinx::AIE::WireBundle::South; - case StrmSwPortType::WEST: - return xilinx::AIE::WireBundle::West; - case StrmSwPortType::NORTH: - return xilinx::AIE::WireBundle::North; - case StrmSwPortType::EAST: - return xilinx::AIE::WireBundle::East; - case StrmSwPortType::TRACE: - return xilinx::AIE::WireBundle::Trace; - case StrmSwPortType::NOC: - return xilinx::AIE::WireBundle::NOC; - case StrmSwPortType::CTRL: - return xilinx::AIE::WireBundle::Ctrl; - default: - llvm::report_fatal_error("unhandled xilinx::AIE::WireBundle"); - } -} - TileOp getOrCreateTile(OpBuilder &builder, DeviceOp &device, int col, int row) { for (auto tile : device.getOps()) { if (tile.getCol() == col && tile.getRow() == row) return tile; @@ -151,7 +96,7 @@ struct ConvertFlowsToInterconnect : OpConversionPattern { auto srcTile = llvm::cast(flowOp.getSource().getDefiningOp()); TileLoc srcCoords = {static_cast(srcTile.getCol()), static_cast(srcTile.getRow())}; - StrmSwPortType srcBundle = toStrmT(flowOp.getSourceBundle()); + StrmSwPortType srcBundle = (flowOp.getSourceBundle()); int srcChannel = flowOp.getSourceChannel(); Port srcPort = {srcBundle, srcChannel}; PathEndPoint srcPe{srcCoords.col, srcCoords.row, srcPort}; @@ -184,9 +129,9 @@ struct ConvertFlowsToInterconnect : OpConversionPattern { Block &b = op->getRegion(0).front(); OpBuilder::InsertionGuard g(rewriter); rewriter.setInsertionPoint(b.getTerminator()); - rewriter.create(rewriter.getUnknownLoc(), - toWireB(conn.src.bundle), conn.src.channel, - toWireB(conn.dst.bundle), conn.dst.channel); + rewriter.create(rewriter.getUnknownLoc(), (conn.src.bundle), + conn.src.channel, (conn.dst.bundle), + conn.dst.channel); } } @@ -245,12 +190,12 @@ LogicalResult runOnPacketFlow( for (Operation &Op : b.getOperations()) { if (auto pktSource = llvm::dyn_cast(Op)) { srcTile = llvm::cast(pktSource.getTile().getDefiningOp()); - srcPort = {toStrmT(pktSource.getBundle()), + srcPort = {(pktSource.getBundle()), static_cast(pktSource.getChannel())}; srcCoords = {srcTile.getCol(), srcTile.getRow()}; } else if (auto pktDest = llvm::dyn_cast(Op)) { TileOp destTile = llvm::cast(pktDest.getTile().getDefiningOp()); - Port destPort = {toStrmT(pktDest.getBundle()), pktDest.getChannel()}; + Port destPort = {(pktDest.getBundle()), pktDest.getChannel()}; TileLoc destCoord = {destTile.getCol(), destTile.getRow()}; if (pktFlowOp->hasAttr("keep_pkt_header")) keepPktHeaderAttr[PhysPort{destCoord, destPort}] = @@ -343,8 +288,8 @@ LogicalResult runOnPacketFlow( amsels.push_back(amselOps[msel]); } auto msOp = builder.create( - builder.getUnknownLoc(), builder.getIndexType(), - toWireB(tileMaster.bundle), tileMaster.channel, amsels); + builder.getUnknownLoc(), builder.getIndexType(), (tileMaster.bundle), + tileMaster.channel, amsels); if (auto pktFlowAttrs = keepPktHeaderAttr[{tileLoc, tileMaster}]) msOp->setAttr("keep_pkt_header", pktFlowAttrs); } @@ -369,7 +314,7 @@ LogicalResult runOnPacketFlow( PacketRulesOp packetrules; if (slaveRules.count(slave) == 0) { packetrules = builder.create( - builder.getUnknownLoc(), toWireB(slave.bundle), slave.channel); + builder.getUnknownLoc(), (slave.bundle), slave.channel); PacketRulesOp::ensureTerminator(packetrules.getRules(), builder, builder.getUnknownLoc()); slaveRules[slave] = packetrules; @@ -413,44 +358,43 @@ LogicalResult runOnPacketFlow( for (Operation &op : switchbox.getConnections().getOps()) { // check if there is MM2S DMA in the switchbox of the 0th row if (auto pktrules = llvm::dyn_cast(op); - pktrules && - toStrmT(pktrules.getSourceBundle()) == StrmSwPortType::DMA) { + pktrules && (pktrules.getSourceBundle()) == StrmSwPortType::DMA) { // If there is, then it should be put into the corresponding shimmux OpBuilder::InsertionGuard g(builder); Block &b0 = shimMuxOp.getConnections().front(); builder.setInsertionPointToStart(&b0); - pktrules.setSourceBundle(toWireB(StrmSwPortType::SOUTH)); + pktrules.setSourceBundle((StrmSwPortType::SOUTH)); if (pktrules.getSourceChannel() == 0) { pktrules.setSourceChannel(3); builder.create(builder.getUnknownLoc(), - toWireB(StrmSwPortType::DMA), 0, - toWireB(StrmSwPortType::NORTH), 3); + (StrmSwPortType::DMA), 0, + (StrmSwPortType::NORTH), 3); } else if (pktrules.getSourceChannel() == 1) { pktrules.setSourceChannel(7); builder.create(builder.getUnknownLoc(), - toWireB(StrmSwPortType::DMA), 1, - toWireB(StrmSwPortType::NORTH), 7); + (StrmSwPortType::DMA), 1, + (StrmSwPortType::NORTH), 7); } } // check if there is S2MM DMA in the switchbox of the 0th row if (auto mtset = llvm::dyn_cast(op); - mtset && toStrmT(mtset.getDestBundle()) == StrmSwPortType::DMA) { + mtset && (mtset.getDestBundle()) == StrmSwPortType::DMA) { // If there is, then it should be put into the corresponding shimmux OpBuilder::InsertionGuard g(builder); Block &b0 = shimMuxOp.getConnections().front(); builder.setInsertionPointToStart(&b0); - mtset.setDestBundle(toWireB(StrmSwPortType::SOUTH)); + mtset.setDestBundle((StrmSwPortType::SOUTH)); if (mtset.getDestChannel() == 0) { mtset.setDestChannel(2); builder.create(builder.getUnknownLoc(), - toWireB(StrmSwPortType::NORTH), 2, - toWireB(StrmSwPortType::DMA), 0); + (StrmSwPortType::NORTH), 2, + (StrmSwPortType::DMA), 0); } else if (mtset.getDestChannel() == 1) { mtset.setDestChannel(3); builder.create(builder.getUnknownLoc(), - toWireB(StrmSwPortType::NORTH), 3, - toWireB(StrmSwPortType::DMA), 1); + (StrmSwPortType::NORTH), 3, + (StrmSwPortType::DMA), 1); } } } @@ -494,9 +438,8 @@ void AIEPathfinderPass::runOnOperation() { TileOp dstTile = llvm::cast(flowOp.getDest().getDefiningOp()); TileLoc srcCoords = {srcTile.getCol(), srcTile.getRow()}; TileLoc dstCoords = {dstTile.getCol(), dstTile.getRow()}; - Port srcPort = {toStrmT(flowOp.getSourceBundle()), - flowOp.getSourceChannel()}; - Port dstPort = {toStrmT(flowOp.getDestBundle()), flowOp.getDestChannel()}; + Port srcPort = {(flowOp.getSourceBundle()), flowOp.getSourceChannel()}; + Port dstPort = {(flowOp.getDestBundle()), flowOp.getDestChannel()}; pathfinder.addFlow(srcCoords, srcPort, dstCoords, dstPort, false); } @@ -509,11 +452,11 @@ void AIEPathfinderPass::runOnOperation() { for (Operation &op : b.getOperations()) { if (auto pktSource = llvm::dyn_cast(op)) { srcTile = llvm::cast(pktSource.getTile().getDefiningOp()); - srcPort = {toStrmT(pktSource.getBundle()), pktSource.getChannel()}; + srcPort = {(pktSource.getBundle()), pktSource.getChannel()}; srcCoords = {srcTile.getCol(), srcTile.getRow()}; } else if (auto pktDest = llvm::dyn_cast(op)) { TileOp dstTile = llvm::cast(pktDest.getTile().getDefiningOp()); - Port dstPort = {toStrmT(pktDest.getBundle()), pktDest.getChannel()}; + Port dstPort = {(pktDest.getBundle()), pktDest.getChannel()}; TileLoc dstCoords = {dstTile.getCol(), dstTile.getRow()}; assert(srcPort.bundle != StrmSwPortType::SS_PORT_TYPE_MAX && srcPort.channel != -1 && "expected srcPort to have been set"); @@ -529,8 +472,8 @@ void AIEPathfinderPass::runOnOperation() { std::vector> connects; for (ConnectOp connectOp : switchboxOp.getOps()) { connects.emplace_back( - toStrmT(connectOp.getSourceBundle()), connectOp.getSourceChannel(), - toStrmT(connectOp.getDestBundle()), connectOp.getDestChannel()); + (connectOp.getSourceBundle()), connectOp.getSourceChannel(), + (connectOp.getDestBundle()), connectOp.getDestChannel()); } TileOp t = xilinx::AIE::getTileOp(*switchboxOp.getOperation()); if (!pathfinder.addFixedConnection(t.getCol(), t.getRow(), connects)) { diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp index cba0548c5..b352697f7 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp @@ -26,6 +26,7 @@ using namespace mlir; using namespace mlir::iree_compiler::AMDAIE; +using xilinx::AIE::AIEObjectFifoType; using xilinx::AIE::BDDimLayoutArrayArrayAttr; using xilinx::AIE::BDDimLayoutArrayAttr; using xilinx::AIE::BDDimLayoutAttr; @@ -33,7 +34,6 @@ using xilinx::AIE::BufferOp; using xilinx::AIE::CoreOp; using xilinx::AIE::DeviceOp; using xilinx::AIE::DMABDOp; -using xilinx::AIE::DMAChannelDirAttr; using xilinx::AIE::DMAStartOp; using xilinx::AIE::EndOp; using xilinx::AIE::FlowOp; @@ -423,8 +423,9 @@ void createAMDAIETileDMA( if (objFifoLinks.contains(linkOp.value())) target = objFifoLinks.at(linkOp.value()); - auto fifo = createOp.getElemType(); - int64_t len = fifo.getNumElements(); + auto fifo = llvm::cast(createOp.getElemType()); + auto elemType = llvm::cast(fifo.getElementType()); + int64_t len = elemType.getNumElements(); createDMA(device, builder, createOp, target, channelDir, channelIndex, dims, numBlocks, /*acqNum*/ 1, /*relNum*/ 1, len, /*offset*/ 0, @@ -442,8 +443,9 @@ void createMemTileDMA( size_t numBlocks = objFifoSize(createOp); if (numBlocks == 0) return; - auto fifo = createOp.getElemType(); - int64_t lenOut = fifo.getNumElements(); + auto fifo = llvm::cast(createOp.getElemType()); + auto elemType = llvm::cast(fifo.getElementType()); + int64_t lenOut = elemType.getNumElements(); size_t acqNum = 1; size_t relNum = 1; // offset based on order of this op in join/distribute list @@ -459,9 +461,10 @@ void createMemTileDMA( relNum = size; } else for (auto fifoIn : fifos) { - auto fifoType = fifoIn.getElemType(); - if (name(fifoIn) == name(createOp)) break; - extraOffset += fifoType.getNumElements(); + auto fifoType = llvm::cast(fifoIn.getElemType()); + auto fifoElemType = llvm::cast(fifoType.getElementType()); + if (fifoIn.name() == createOp.name()) break; + extraOffset += fifoElemType.getNumElements(); } }; @@ -480,8 +483,9 @@ void createMemTileDMA( linkOp->getFifoOuts().size()); } else if (target != createOp) { - auto targetFifo = target.getElemType(); - lenOut = targetFifo.getNumElements(); + auto targetFifo = llvm::cast(target.getElemType()); + auto targetElemType = llvm::cast(targetFifo.getElementType()); + lenOut = targetElemType.getNumElements(); } // check if current createOp is of smaller size in link @@ -622,7 +626,7 @@ void splitFifo( }; int consumerIndex = 0; - auto datatype = createOp.getElemType(); + auto datatype = cast(createOp.getElemType()); MLIRContext *ctx = builder.getContext(); std::vector splitConsumerFifos; for (auto consumerTile : createOp.getConsumerTiles()) { @@ -828,7 +832,8 @@ void createBuffersAndLocks( if (!objFifoSize(createOp)) return; - MemRefType fifoType = createOp.getElemType(); + auto fifo = llvm::cast(createOp.getElemType()); + auto elemType = llvm::cast(fifo.getElementType()); // if this objectFifo is linked to another, check if the other's elements // have already been created (the elements that are created are those of @@ -844,11 +849,15 @@ void createBuffersAndLocks( // if distribute, fifoIn has bigger size if (isDistribute(*linkOp) && name(createOp) != name(fifoIn)) return; - auto fifoInType = getInputObjectFifos(*linkOp)[0].getElemType(), - fifoOutType = getOutputObjectFifos(*linkOp)[0].getElemType(); - int64_t inSize = fifoInType.getNumElements(); - if (int64_t outSize = fifoOutType.getNumElements(); inSize >= outSize) { - if (name(createOp) != name(fifoIn)) return; + auto fifoInType = llvm::cast( + getInputObjectFifos(*linkOp)[0].getElemType()), + fifoOutType = llvm::cast( + getOutputObjectFifos(*linkOp)[0].getElemType()); + auto elemInType = llvm::cast(fifoInType.getElementType()), + elemOutType = llvm::cast(fifoOutType.getElementType()); + int64_t inSize = elemInType.getNumElements(); + if (int64_t outSize = elemOutType.getNumElements(); inSize >= outSize) { + if (createOp.name() != fifoIn.name()) return; } else if (getOutputObjectFifos(*linkOp)[0] != createOp) return; } @@ -876,7 +885,7 @@ void createBuffersAndLocks( // create as many locks as there are external buffers for (int ofElemIndex = 0; ofElemIndex < numElem; ofElemIndex++) { auto buff = builder.create( - builder.getUnknownLoc(), fifoType, creationTile, + builder.getUnknownLoc(), elemType, creationTile, builder.getStringAttr(name(createOp).str() + "_buff_" + std::to_string(ofElemIndex)), /*address*/ nullptr, @@ -1126,7 +1135,8 @@ struct AMDAIEObjectFifoStatefulTransformPass : mlir::OperationPass { auto symName = createOp.getName(); createOp->setAttr(SymbolTable::getSymbolAttrName(), builder.getStringAttr("__erase_" + symName)); - auto memrefType = createOp.getElemType(); + auto memrefType = llvm::cast(createOp.getElemType()) + .getElementType(); builder.create(builder.getUnknownLoc(), symName, builder.getStringAttr("public"), memrefType, nullptr, false, nullptr); diff --git a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt index 28cf0b492..3bb46e08c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt @@ -23,6 +23,16 @@ iree_tablegen_library( -gen-enum-defs AIEEnums.cpp.inc ) +iree_tablegen_library( + NAME + AIETypesGen + TD_FILE + AIETypes.td + OUTS + -gen-typedef-decls AIETypes.h.inc + -gen-typedef-defs AIETypes.cpp.inc +) + iree_tablegen_library( NAME AIEDialectGen @@ -43,6 +53,8 @@ iree_tablegen_library( -gen-op-interface-defs AIEInterfaces.cpp.inc ) +list(APPEND IREE_COMPILER_TABLEGEN_INCLUDE_DIRS + ${IREE_AMD_AIE_RUNTIME_SOURCE_DIR}) iree_tablegen_library( NAME AIEOpsGen @@ -73,6 +85,7 @@ iree_cc_library( ::AIEDialectGen ::AIEInterfacesGen ::AIEOpsGen + ::AIETypesGen # mlir::DataLayout::closest(mlir::Operation*) MLIRDataLayoutInterfaces # mlir::OffsetSizeAndStrideOpInterface::getOffsets() diff --git a/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt index 3281a2acd..58f32117e 100644 --- a/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt @@ -21,6 +21,22 @@ iree_cc_library( # AIR Dialect ############################################################################### +function(replace_string_in_file _file _match_string _replace_string) + if(NOT (EXISTS ${_file})) + message(FATAL_ERROR "file ${_file} does not exist") + endif() + file(READ "${_file}" _file_contents) + if(_file_contents STREQUAL "") + message(FATAL_ERROR "empty file contents for ${_file}") + endif() + string(REPLACE "${_match_string}" "${_replace_string}" _file_contents "${_file_contents}") + if(_file_contents STREQUAL "") + message(FATAL_ERROR "empty replacement contents for ${_file}") + endif() + file(WRITE "${_file}" "${_file_contents}") +endfunction() + + iree_cc_library( NAME AIRDialectIR @@ -164,6 +180,43 @@ iree_cc_library( MLIRTransforms ) +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIESchedulingUtils.cpp + "target_model.getTargetArch()" "AIE::AIEArch::AIE2") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIESchedulingUtils.cpp + "AIE::WireBundle::DMA" "mlir::iree_compiler::AMDAIE::StrmSwPortType::DMA") + +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "target_model.getTargetArch()" "AIE::AIEArch::AIE2") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "device.getTargetModel().getTargetArch()" "AIE::AIEArch::AIE2") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "AIE::AIETargetModel" "mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "/*initial_value*/ nullptr," "") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "AIE::TileID" "mlir::iree_compiler::AMDAIE::TileLoc") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "AIE::WireBundle::Trace" "mlir::iree_compiler::AMDAIE::StrmSwPortType::TRACE") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp + "memtileToSizeMap[t] = m.getTargetModel().getMemTileSize()" + "memtileToSizeMap[t] = m.getTargetModel().getMemTileSize(t.getCol(), t.getRow())") + +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRRtToNpuPass.cpp + "&target_model" "target_model") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRRtToNpuPass.cpp + "AIE::WireBundle::Trace" "mlir::iree_compiler::AMDAIE::StrmSwPortType::TRACE") + iree_cc_library( NAME AIRConversionPasses diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp index 9e1bc792c..40eaa2f73 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetCDODirect.cpp @@ -31,7 +31,6 @@ using namespace mlir; using xilinx::AIE::AMSelOp; using xilinx::AIE::BufferOp; -using xilinx::AIE::CascadeDir; using xilinx::AIE::ConnectOp; using xilinx::AIE::CoreOp; using xilinx::AIE::DeviceOp; @@ -56,50 +55,6 @@ using Path = std::filesystem::path; namespace { -mlir::iree_compiler::AMDAIE::StrmSwPortType toAMDAIEStrmT(WireBundle w) { - using mlir::iree_compiler::AMDAIE::StrmSwPortType; - switch (w) { - case WireBundle::Core: - return StrmSwPortType::CORE; - case WireBundle::DMA: - return StrmSwPortType::DMA; - case WireBundle::FIFO: - return StrmSwPortType::FIFO; - case WireBundle::South: - return StrmSwPortType::SOUTH; - case WireBundle::West: - return StrmSwPortType::WEST; - case WireBundle::North: - return StrmSwPortType::NORTH; - case WireBundle::East: - return StrmSwPortType::EAST; - case WireBundle::PLIO: - llvm::report_fatal_error("unhandled PLIO"); - case WireBundle::NOC: - return StrmSwPortType::NOC; - case WireBundle::Trace: - return StrmSwPortType::TRACE; - case WireBundle::Ctrl: - return StrmSwPortType::CTRL; - default: - llvm::report_fatal_error("unhandled WireBundle"); - } -} - -mlir::iree_compiler::AMDAIE::Cascade::Direction toDir(CascadeDir dir) { - switch (dir) { - case xilinx::AIE::CascadeDir::South: - return mlir::iree_compiler::AMDAIE::Cascade::Direction::SOUTH; - case xilinx::AIE::CascadeDir::North: - return mlir::iree_compiler::AMDAIE::Cascade::Direction::NORTH; - case xilinx::AIE::CascadeDir::West: - return mlir::iree_compiler::AMDAIE::Cascade::Direction::WEST; - case xilinx::AIE::CascadeDir::East: - return mlir::iree_compiler::AMDAIE::Cascade::Direction::EAST; - } - llvm::report_fatal_error("unhandled cascade dir"); -} - mlir::iree_compiler::AMDAIE::Lock::Action toLock(xilinx::AIE::LockAction l) { switch (l) { case xilinx::AIE::LockAction::Acquire: @@ -289,11 +244,10 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, SwitchBox swb = {t.getCol(), t.getRow()}; std::vector connects; for (auto connectOp : switchboxOp.getOps()) { - connects.emplace_back(Port{toAMDAIEStrmT(connectOp.getSourceBundle()), - connectOp.getSourceChannel()}, - Port{toAMDAIEStrmT(connectOp.getDestBundle()), - connectOp.getDestChannel()}, - Connect::Interconnect::SWB, swb.col, swb.row); + connects.emplace_back( + Port{connectOp.getSourceBundle(), connectOp.getSourceChannel()}, + Port{connectOp.getDestBundle(), connectOp.getDestChannel()}, + Connect::Interconnect::SWB, swb.col, swb.row); } if (failed(configureStreamSwitch(deviceModel, swb, connects))) { return failure(); @@ -308,7 +262,7 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, static_cast(amsel.getMsel())}); } if (failed(configureSwitchPacketMasters( - deviceModel, swb, toAMDAIEStrmT(masterSetOp.getDestBundle()), + deviceModel, swb, masterSetOp.getDestBundle(), masterSetOp.getDestChannel(), amSels, masterSetOp->hasAttr("keep_pkt_header")))) return failure(); @@ -321,11 +275,9 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, AMSelOp amselOp = cast(packetRuleOp.getAmsel().getDefiningOp()); if (failed(configureSwitchPacketSlaves( - deviceModel, swb, - toAMDAIEStrmT(packetRulesOp.getSourceBundle()), + deviceModel, swb, packetRulesOp.getSourceBundle(), packetRulesOp.getSourceChannel(), - AMSel{static_cast(amselOp.getArbiterID()), - static_cast(amselOp.getMsel())}, + AMSel{amselOp.getArbiterID(), amselOp.getMsel()}, packetRuleOp.getValue(), packetRuleOp.getMask(), slot))) return failure(); slot++; @@ -338,11 +290,10 @@ LogicalResult addInitConfigToCDO(const AMDAIEDeviceModel &deviceModel, SwitchBox swb = {t.getCol(), t.getRow()}; std::vector connects; for (auto connectOp : muxOp.getOps()) { - connects.emplace_back(Port{toAMDAIEStrmT(connectOp.getSourceBundle()), - connectOp.getSourceChannel()}, - Port{toAMDAIEStrmT(connectOp.getDestBundle()), - connectOp.getDestChannel()}, - Connect::Interconnect::SHIMMUX, swb.col, swb.row); + connects.emplace_back( + Port{connectOp.getSourceBundle(), connectOp.getSourceChannel()}, + Port{connectOp.getDestBundle(), connectOp.getDestChannel()}, + Connect::Interconnect::SHIMMUX, swb.col, swb.row); } if (failed(configureStreamSwitch(deviceModel, swb, connects))) { return failure(); diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp index 9a175c4a7..8c1f21e48 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIELowerToAIE.cpp @@ -128,11 +128,12 @@ AIE::ObjectFifoCreateOp createObjectFifo(IRRewriter &rewriter, : MemRefType::get({targetSize}, dstType.getElementType(), MemRefLayoutAttrInterface{}, rewriter.getI64IntegerAttr(1)); + AIE::AIEObjectFifoType dtype = AIE::AIEObjectFifoType::get(memrefType); auto depthInBytes = srcType.getElementTypeBitWidth() / 8; auto fifo = rewriter.create( rewriter.getUnknownLoc(), symName, srcTile, dstTiles, - rewriter.getIntegerAttr(rewriter.getI32Type(), depthInBytes), - llvm::cast(memrefType), sourceDims, targetDims); + rewriter.getIntegerAttr(rewriter.getI32Type(), depthInBytes), dtype, + sourceDims, targetDims); return fifo; } @@ -201,9 +202,11 @@ LogicalResult acquireOpToAIE(IRRewriter &rewriter, return acquireOp.emitError() << "input isn't mapped to an `aie.objectifo` operation"; } - MemRefType elementType = MemRefType::Builder(objFifo.getElemType()) + AIE::AIEObjectFifoType ofTy = + cast(objFifo.getElemType()); + MemRefType elementType = MemRefType::Builder(ofTy.getElementType()) .setMemorySpace(rewriter.getI64IntegerAttr(1)); - auto subviewType = elementType; + auto subviewType = AIE::AIEObjectFifoSubviewType::get(elementType); AIE::ObjectFifoPort port = acquireOp.getPort() == LogicalObjectFifoPort::Produce ? AIE::ObjectFifoPort::Produce diff --git a/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td b/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td index 8fd168ca1..ec80404d2 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td +++ b/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td @@ -36,4 +36,24 @@ def DMAChannelDir: I32EnumAttr<"DMAChannelDir", let cppNamespace = "mlir::iree_compiler::AMDAIE"; } +def StrmSwPortType: I32EnumAttr<"StrmSwPortType", "", + [ + I32EnumAttrCase<"CORE", 0>, + I32EnumAttrCase<"DMA", 1>, + I32EnumAttrCase<"CTRL", 2>, + I32EnumAttrCase<"FIFO", 3>, + I32EnumAttrCase<"SOUTH", 4>, + I32EnumAttrCase<"WEST", 5>, + I32EnumAttrCase<"NORTH", 6>, + I32EnumAttrCase<"EAST", 7>, + I32EnumAttrCase<"TRACE", 8>, + I32EnumAttrCase<"UCTRLR", 9>, + I32EnumAttrCase<"SS_PORT_TYPE_MAX", 10>, + // "illegal" types after max + I32EnumAttrCase<"NOC", 11> + ]> +{ + let cppNamespace = "mlir::iree_compiler::AMDAIE"; +} + #endif // IREE_AIE_RUNTIME_AMDAIEENUMS diff --git a/runtime/src/iree-amd-aie/aie_runtime/CMakeLists.txt b/runtime/src/iree-amd-aie/aie_runtime/CMakeLists.txt index b8ec1077c..2f5d6d452 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/CMakeLists.txt +++ b/runtime/src/iree-amd-aie/aie_runtime/CMakeLists.txt @@ -39,26 +39,26 @@ message(STATUS "OpenSSL include directories:" ${OPENSSL_INCLUDE_DIR}) # https://stackoverflow.com/a/49216539/9045206 function(remove_flag_from_target _target _flag) - get_target_property(_target_cxx_flags ${_target} COMPILE_OPTIONS) - if(_target_cxx_flags) - list(REMOVE_ITEM _target_cxx_flags ${_flag}) - set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${_target_cxx_flags}") - endif() + get_target_property(_target_cxx_flags ${_target} COMPILE_OPTIONS) + if(_target_cxx_flags) + list(REMOVE_ITEM _target_cxx_flags ${_flag}) + set_target_properties(${_target} PROPERTIES COMPILE_OPTIONS "${_target_cxx_flags}") + endif() endfunction() function(replace_string_in_file _file _match_string _replace_string) - if(NOT (EXISTS ${_file})) - message(FATAL_ERROR "file ${_file} does not exist") - endif() - file(READ "${_file}" _file_contents) - if(_file_contents STREQUAL "") - message(FATAL_ERROR "empty file contents for ${_file}") - endif() - string(REPLACE "${_match_string}" "${_replace_string}" _file_contents "${_file_contents}") - if(_file_contents STREQUAL "") - message(FATAL_ERROR "empty replacement contents for ${_file}") - endif() - file(WRITE "${_file}" "${_file_contents}") + if(NOT (EXISTS ${_file})) + message(FATAL_ERROR "file ${_file} does not exist") + endif() + file(READ "${_file}" _file_contents) + if(_file_contents STREQUAL "") + message(FATAL_ERROR "empty file contents for ${_file}") + endif() + string(REPLACE "${_match_string}" "${_replace_string}" _file_contents "${_file_contents}") + if(_file_contents STREQUAL "") + message(FATAL_ERROR "empty replacement contents for ${_file}") + endif() + file(WRITE "${_file}" "${_file_contents}") endfunction() # ############################################################################## diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_router.h b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_router.h index cfc829158..e14ae7ee2 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_router.h +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_router.h @@ -20,7 +20,8 @@ struct Port { StrmSwPortType bundle; int channel; - Port() = delete; + // mlir-air legacy + Port() : bundle(), channel() {} Port(StrmSwPortType b, int c) : bundle(b), channel(c) {} typedef std::tuple TupleType; Port(TupleType t) : Port(std::get<0>(t), std::get<1>(t)) {} diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc index ee2d29f88..22b9a5bf7 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc @@ -79,13 +79,6 @@ bool isAieRtCompatStrmSwPortType( ::StrmSwPortType checkedAieRtCompatStrmSwPortType( mlir::iree_compiler::AMDAIE::StrmSwPortType t, const char *file, unsigned int line, const char *function) { -#ifndef NDEBUG - if (!isAieRtCompatStrmSwPortType(t)) { - llvm::report_fatal_error(llvm::formatv( - "{0}:{1}:{2}: StrmSwPortType incompatible with aie-rt: {3}", file, - line, function, to_string(t))); - } -#endif return static_cast<::StrmSwPortType>(t); } // macro so that line numbers are preserved for where the check fails @@ -96,7 +89,8 @@ ::StrmSwPortType checkedAieRtCompatStrmSwPortType( namespace mlir::iree_compiler::AMDAIE { -StrmSwPortType getConnectingBundle(StrmSwPortType dir) { +::mlir::iree_compiler::AMDAIE::StrmSwPortType getConnectingBundle( + StrmSwPortType dir) { switch (dir) { case StrmSwPortType::NORTH: return StrmSwPortType::SOUTH; diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h index 8814bba25..1f1b98c6d 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h @@ -134,29 +134,19 @@ enum class AMDAIEDmaBdProp : uint8_t { MAX = sizeof(XAie_DmaBdProp) }; -enum class StrmSwPortType : uint8_t { - CORE = ::StrmSwPortType::CORE, - DMA, - CTRL, - FIFO, - SOUTH, - WEST, - NORTH, - EAST, - TRACE, - UCTRLR, - SS_PORT_TYPE_MAX, - // "illegal" types after max - NOC, -}; -static_assert(static_cast(StrmSwPortType::CORE) == 0, - "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " - "aie-rt's StrmSwPortType"); -static_assert(static_cast(StrmSwPortType::SS_PORT_TYPE_MAX) == - ::StrmSwPortType::SS_PORT_TYPE_MAX, - "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " - "aie-rt's StrmSwPortType"); -inline ::StrmSwPortType strmTtoStrmT(StrmSwPortType t) { +static_assert( + static_cast(::mlir::iree_compiler::AMDAIE::StrmSwPortType::CORE) == + ::StrmSwPortType::CORE, + "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " + "aie-rt's StrmSwPortType"); +static_assert( + static_cast( + ::mlir::iree_compiler::AMDAIE::StrmSwPortType::SS_PORT_TYPE_MAX) == + ::StrmSwPortType::SS_PORT_TYPE_MAX, + "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " + "aie-rt's StrmSwPortType"); +inline ::StrmSwPortType strmTtoStrmT( + ::mlir::iree_compiler::AMDAIE::StrmSwPortType t) { return static_cast<::StrmSwPortType>(t); } @@ -289,17 +279,27 @@ struct AMDAIEDeviceModel { uint32_t getNumBDs(uint8_t col, uint8_t row) const; - uint32_t getNumSourceSwitchBoxConnections(uint8_t col, uint8_t row, - StrmSwPortType bundle) const; - uint32_t getNumDestSwitchBoxConnections(uint8_t col, uint8_t row, - StrmSwPortType bundle) const; - bool isLegalTileConnection(uint8_t col, uint8_t row, StrmSwPortType srcBundle, - uint8_t srcChan, StrmSwPortType dstBundle, - uint8_t dstChan) const; + uint32_t getNumSourceSwitchBoxConnections( + uint8_t col, uint8_t row, + ::mlir::iree_compiler::AMDAIE::StrmSwPortType bundle) const; + uint32_t getNumDestSwitchBoxConnections( + uint8_t col, uint8_t row, + ::mlir::iree_compiler::AMDAIE::StrmSwPortType bundle) const; + bool isLegalTileConnection( + uint8_t col, uint8_t row, + ::mlir::iree_compiler::AMDAIE::StrmSwPortType srcBundle, uint8_t srcChan, + ::mlir::iree_compiler::AMDAIE::StrmSwPortType dstBundle, + uint8_t dstChan) const; uint32_t getColumnShift() const; uint32_t getRowShift() const; + // mlir-air legacy + uint32_t getNumDestSwitchboxConnections( + int col, int row, + ::mlir::iree_compiler::AMDAIE::StrmSwPortType bundle) const; + uint32_t getNumMemTileRows() const { return 1; } + /// Return a map from channels to valid BD ids for the requested tile type. /// TODO(jornt): find these ranges in the device model. DenseMap> getChannelToValidBdIds( @@ -309,7 +309,8 @@ struct AMDAIEDeviceModel { }; struct AMDAIEDeviceModel getDeviceModel(AMDAIEDevice device); -StrmSwPortType getConnectingBundle(StrmSwPortType dir); +::mlir::iree_compiler::AMDAIE::StrmSwPortType getConnectingBundle( + ::mlir::iree_compiler::AMDAIE::StrmSwPortType dir); bool isNPUDevice(mlir::iree_compiler::AMDAIE::AMDAIEDevice d); /// ============================= BEGIN ================================== diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt b/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt index 869820505..227bda174 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt +++ b/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt @@ -31,16 +31,16 @@ iree_lit_test( "hostonly" ) -iree_cc_test( - NAME - DeviceModelTestCppTest - SRCS - DeviceModelTest.cpp - DEPS - gtest - iree::target::amd-aie::aie::AIEDialectIR - iree-amd-aie::aie_runtime::iree_aie_runtime_static -) +#iree_cc_test( +# NAME +# DeviceModelTestCppTest +# SRCS +# DeviceModelTest.cpp +# DEPS +# gtest +# iree::target::amd-aie::aie::AIEDialectIR +# iree-amd-aie::aie_runtime::iree_aie_runtime_static +#) iree_cc_test( NAME @@ -106,9 +106,9 @@ iree_lit_test( ) -target_include_directories( - iree-amd-aie_aie_runtime_test_DeviceModelTestCppTest - PRIVATE "${IREE_MLIR_AIE_SOURCE_DIR}/include" -) +#target_include_directories( +# iree-amd-aie_aie_runtime_test_DeviceModelTestCppTest +# PRIVATE "${IREE_MLIR_AIE_SOURCE_DIR}/include" +#) add_subdirectory(cdo) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp b/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp index 63bf66110..91748e150 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp +++ b/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp @@ -18,7 +18,7 @@ extern "C" { #undef u64 } -#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/AIEDialect.h" #include "aie/Dialect/AIE/IR/AIETargetModel.h" #include "gtest/gtest-param-test.h" #include "gtest/gtest.h" diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/aie_cdo_gen_test.cxx b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/aie_cdo_gen_test.cxx index d73da2e1d..fcc0d39d7 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/aie_cdo_gen_test.cxx +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/aie_cdo_gen_test.cxx @@ -4,10 +4,11 @@ // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +#include #include -#include "aie/Dialect/AIE/IR/AIEDialect.h" -#include "aie/Dialect/AIEX/IR/AIEXDialect.h" +#include "aie/AIEDialect.h" +#include "aie/AIEXDialect.h" #include "iree-amd-aie/Target/AMDAIETargets.h" #include "iree-amd-aie/Target/XCLBinGen.h" #include "llvm/Support/Debug.h" From 6726ba389c1359d26bb2dc95b466753d6fa703ff Mon Sep 17 00:00:00 2001 From: max Date: Tue, 6 Aug 2024 13:21:23 -0500 Subject: [PATCH 08/12] first compile --- .../plugins/target/AMD-AIE/aie/AIEAttrs.td | 8 + .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 2 - .../plugins/target/AMD-AIE/aie/AIEDialect.h | 100 ++++++---- .../target/AMD-AIE/aie/AIEInterfaces.td | 24 --- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 23 +-- .../plugins/target/AMD-AIE/aie/AIETypes.td | 4 + compiler/plugins/target/AMD-AIE/aie/AIEX.td | 12 +- .../target/AMD-AIE/aie/AIEXDialect.cpp | 188 +++--------------- .../plugins/target/AMD-AIE/aie/AIEXDialect.h | 19 ++ .../plugins/target/AMD-AIE/aie/CMakeLists.txt | 11 - .../plugins/target/AMD-AIE/air/CMakeLists.txt | 4 + .../iree-amd-aie/aie_runtime/AMDAIEEnums.td | 20 -- .../aie_runtime/iree_aie_runtime.cc | 16 +- .../aie_runtime/iree_aie_runtime.h | 68 ++++--- 14 files changed, 181 insertions(+), 318 deletions(-) delete mode 100644 compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td index 225545075..e739099f1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td @@ -124,4 +124,12 @@ def BDPadLayoutArrayAttr : ArrayOfAttr< /*eltName*/BDPadLayoutAttr.cppClassName >; +def StrmSwPortTypeAttr : Attr, ""> { + let storageType = [{ ::mlir::IntegerAttr }]; + let returnType = [{ ::mlir::iree_compiler::AMDAIE::StrmSwPortType }]; + let valueType = I32; + let constBuilderCall = "$_builder.getI32IntegerAttr(static_cast($0))"; + code convertFromStorage = "::mlir::iree_compiler::AMDAIE::StrmSwPortType($_self.getValue().getZExtValue())"; +} + #endif // AIE_ATTRS \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index 228c2e41e..0c367a0ff 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -137,7 +137,6 @@ static ParseResult parse(Type &result, StringRef name, return failure(); } -/// Parse an instance of a type registered to the AIE dialect. Type AIEDialect::parseType(DialectAsmParser &parser) const { StringRef name; Type result; @@ -145,7 +144,6 @@ Type AIEDialect::parseType(DialectAsmParser &parser) const { return result; } -/// Print an instance of a type registered to the AIE dialect. void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { if (llvm::isa(type)) { auto objectFifoType = llvm::cast(type); diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index 7da7cc48e..9b31c18e6 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -43,17 +43,6 @@ mlir::StringAttr name(T &op) { llvm::report_fatal_error("couldn't get name"); } -mlir::LogicalResult myVerifyOffsetSizeAndStrideOp( - mlir::OffsetSizeAndStrideOpInterface op); -template -struct MyOffsetSizeAndStrideOpInterfaceTrait - : public ::mlir::detail::OffsetSizeAndStrideOpInterfaceTrait { - static ::mlir::LogicalResult verifyTrait(::mlir::Operation *op) { - return myVerifyOffsetSizeAndStrideOp( - ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(op)); - } -}; - namespace detail { struct AIEObjectFifoTypeStorage; } @@ -82,15 +71,6 @@ class AIEObjectFifoSubviewType mlir::MemRefType getElementType(); }; -/// Include the generated interface declarations. -#include "aie/AIEInterfaces.h.inc" - -struct MyOffsetSizeAndStrideOpInterface - : ::mlir::OffsetSizeAndStrideOpInterface { - template - struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait {}; -}; - using DMAChannelDir = mlir::iree_compiler::AMDAIE::DMAChannelDir; using Port = mlir::iree_compiler::AMDAIE::Port; using WireBundle = mlir::iree_compiler::AMDAIE::StrmSwPortType; @@ -110,7 +90,7 @@ using DMAChannelDirAttr = mlir::iree_compiler::AMDAIE::DMAChannelDirAttr; namespace xilinx::AIE { -mlir::ParseResult parseObjectFifoProducerTile( +inline mlir::ParseResult parseObjectFifoProducerTile( mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, BDDimLayoutArrayAttr &dimensions) { std::vector emptyDims = {}; @@ -127,9 +107,10 @@ mlir::ParseResult parseObjectFifoProducerTile( return mlir::success(); } -void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, - mlir::Operation *op, mlir::Value operand, - BDDimLayoutArrayAttr dimensions) { +inline void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, + mlir::Operation *op, + mlir::Value operand, + BDDimLayoutArrayAttr dimensions) { printer << operand; if (!dimensions.empty()) { printer << " toStream "; @@ -137,7 +118,7 @@ void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, } } -mlir::ParseResult parseObjectFifoConsumerTiles( +inline mlir::ParseResult parseObjectFifoConsumerTiles( mlir::OpAsmParser &parser, llvm::SmallVectorImpl &tiles, BDDimLayoutArrayArrayAttr &dimensions) { @@ -174,9 +155,9 @@ mlir::ParseResult parseObjectFifoConsumerTiles( return mlir::success(); } -void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, - mlir::Operation *op, mlir::OperandRange tiles, - BDDimLayoutArrayArrayAttr dimsPerTileAttr) { +inline void printObjectFifoConsumerTiles( + mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRange tiles, + BDDimLayoutArrayArrayAttr dimsPerTileAttr) { size_t tileIdx = 0; for (auto tile : tiles) { printer << tile; @@ -197,11 +178,23 @@ inline TileOp getTileOp(mlir::Operation &op) { return llvm::cast(t.getDefiningOp()); } -int32_t getBufferElementTypeWidthInBytes(DMABDOp &op) { +inline TileOp CoreOp::getTileOp() { + return ::xilinx::AIE::getTileOp(*getOperation()); +} + +inline TileOp BufferOp::getTileOp() { + return ::xilinx::AIE::getTileOp(*getOperation()); +} + +inline TileOp ShimDMAOp::getTileOp() { + return ::xilinx::AIE::getTileOp(*getOperation()); +} + +inline int32_t getBufferElementTypeWidthInBytes(DMABDOp &op) { return op.getBuffer().getType().getElementTypeBitWidth() / 8; } -int32_t getLenInBytes(DMABDOp &op) { +inline int32_t getLenInBytes(DMABDOp &op) { if (std::optional len = op.getLen(); len.has_value()) return len.value() * getBufferElementTypeWidthInBytes(op); else @@ -209,31 +202,32 @@ int32_t getLenInBytes(DMABDOp &op) { getBufferElementTypeWidthInBytes(op); } -int32_t getOffsetInBytes(DMABDOp &op) { +inline int32_t getOffsetInBytes(DMABDOp &op) { return op.getOffset() * getBufferElementTypeWidthInBytes(op); } -MemOp getMemOp(TileOp &op) { +inline MemOp getMemOp(TileOp &op) { auto users = op.getResult().getUsers(); for (auto user : users) if (auto memOp = llvm::dyn_cast(*user)) return memOp; return nullptr; } -CoreOp getCoreOp(TileOp &op) { +inline CoreOp getCoreOp(TileOp &op) { auto users = op.getResult().getUsers(); for (auto user : users) if (auto coreOp = llvm::dyn_cast(*user)) return coreOp; return nullptr; } -MemOp TileOp::getMemOp() { return ::xilinx::AIE::getMemOp(*this); } +inline MemOp TileOp::getMemOp() { return ::xilinx::AIE::getMemOp(*this); } -CoreOp TileOp::getCoreOp() { return ::xilinx::AIE::getCoreOp(*this); } +inline CoreOp TileOp::getCoreOp() { return ::xilinx::AIE::getCoreOp(*this); } -void collectBuffers(DeviceOp &device, - llvm::DenseMap> &buffers) { +inline void collectBuffers( + DeviceOp &device, + llvm::DenseMap> + &buffers) { for (BufferOp buffer : device.getOps()) { mlir::Operation *tileOp = buffer.getTile().getDefiningOp(); buffers[tileOp].push_back(buffer); @@ -250,12 +244,12 @@ inline void collectTiles(xilinx::AIE::DeviceOp &device, } } -int64_t getAllocationSize(BufferOp &op) { +inline int64_t getAllocationSize(BufferOp &op) { auto type = llvm::cast(op.getType()); return type.getNumElements() * type.getElementTypeBitWidth() / 8; } -mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( +inline mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( mlir::Operation *op) { if (auto t = llvm::dyn_cast(op)) { return mlir::iree_compiler::AMDAIE::getDeviceModel( @@ -268,7 +262,31 @@ mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( llvm::report_fatal_error("couldn't find device model for op"); } -uint32_t getAddressGenGranularity() { return 32; }; +inline size_t TileOp::getNumDestConnections( + mlir::iree_compiler::AMDAIE::StrmSwPortType s) { + auto deviceModel = getDeviceModel(this->getOperation()); + return deviceModel.getNumDestSwitchBoxConnections(this->getCol(), + this->getRow(), s); +} + +inline size_t TileOp::getNumSourceConnections( + mlir::iree_compiler::AMDAIE::StrmSwPortType s) { + auto deviceModel = getDeviceModel(this->getOperation()); + return deviceModel.getNumSourceSwitchBoxConnections(this->getCol(), + this->getRow(), s); +} + +inline bool TileOp::isMemTile() { + auto deviceModel = getDeviceModel(this->getOperation()); + return deviceModel.isMemTile(this->getCol(), this->getRow()); +} + +inline mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel +DeviceOp::getTargetModel() { + return getDeviceModel(this->getOperation()); +} + +inline uint32_t getAddressGenGranularity() { return 32; }; struct DMAChannel { DMAChannelDir direction; diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td b/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td deleted file mode 100644 index b10b27f14..000000000 --- a/compiler/plugins/target/AMD-AIE/aie/AIEInterfaces.td +++ /dev/null @@ -1,24 +0,0 @@ -//===- AIEInterfaces.td ------------------------------------*- tablegen -*-===// -// -// 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 2020 Xilinx Inc. -// -//===----------------------------------------------------------------------===// - - -#ifndef AIE_INTERFACES -#define AIE_INTERFACES - -include "AIE.td" - -include "mlir/IR/OpBase.td" -include "mlir/IR/EnumAttr.td" -include "mlir/IR/OpAsmInterface.td" - -// Don't delete - see AIEDialect::myVerifyOffsetSizeAndStrideOp -def MyOffsetSizeAndStrideOpInterface: OpInterfaceTrait<"::xilinx::AIE::MyOffsetSizeAndStrideOpInterface"> {} - -#endif // AIE_INTERFACES \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index 9c49d0797..e538be920 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -13,7 +13,6 @@ include "AIE.td" include "AIEAttrs.td" -include "AIEInterfaces.td" include "AIETypes.td" include "iree-amd-aie/aie_runtime/AMDAIEEnums.td" @@ -135,9 +134,9 @@ def AIE_CoreOp: AIE_Op<"core", [ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { let arguments = ( - ins StrmSwPortType:$source_bundle, + ins StrmSwPortTypeAttr:$source_bundle, ConfinedAttr]>:$source_channel, - StrmSwPortType:$dest_bundle, + StrmSwPortTypeAttr:$dest_bundle, ConfinedAttr]>:$dest_channel ); let summary = "A circuit-switched connection inside a switchbox"; @@ -149,10 +148,10 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> def AIE_FlowOp: AIE_Op<"flow", []> { let arguments = ( ins Index:$source, - StrmSwPortType:$source_bundle, + StrmSwPortTypeAttr:$source_bundle, ConfinedAttr]>:$source_channel, Index:$dest, - StrmSwPortType:$dest_bundle, + StrmSwPortTypeAttr:$dest_bundle, ConfinedAttr]>:$dest_channel ); let summary = "A logical circuit-switched connection between cores"; @@ -189,7 +188,7 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let arguments = ( - ins StrmSwPortType:$dest_bundle, + ins StrmSwPortTypeAttr:$dest_bundle, ConfinedAttr]>:$dest_channel, Variadic:$amsels ); @@ -201,7 +200,7 @@ def AIE_MasterSetOp: AIE_Op<"masterset", [ def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"EndOp">]> { let arguments = ( - ins StrmSwPortType:$source_bundle, + ins StrmSwPortTypeAttr:$source_bundle, ConfinedAttr]>:$source_channel ); let regions = (region AnyRegion:$rules); @@ -240,7 +239,7 @@ def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndO def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { let arguments = ( ins Index:$tile, - StrmSwPortType:$bundle, + StrmSwPortTypeAttr:$bundle, ConfinedAttr]>:$channel ); let summary = "A sourceport"; @@ -257,7 +256,7 @@ def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { let arguments = ( ins Index:$tile, - StrmSwPortType:$bundle, + StrmSwPortTypeAttr:$bundle, ConfinedAttr]>:$channel ); let summary = "A destination port"; @@ -592,9 +591,9 @@ def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { ]; } -def AIE_ExternalBufferOp: AIE_Op<"external_buffer", [ - DeclareOpInterfaceMethods - ]>, Results<(outs AnyMemRef)> { +// mlir-air legacy + +def AIE_ExternalBufferOp: AIE_Op<"external_buffer">, Results<(outs AnyMemRef)> { let summary = "Declare a buffer in external memory"; let arguments = (ins OptionalAttr:$sym_name); diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td index 97ccf6a97..e08ee4fc1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td @@ -24,4 +24,8 @@ def AIE_ObjectFifoSubviewType : DialectType($_self)">, "AIE ObjectFifoSubview type">; +def StrmSwPortType : DialectType, "">, + BuildableType<"::mlir::iree_compiler::AMDAIE::StrmSwPortType{}">; + #endif // AIE_TYPES \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEX.td b/compiler/plugins/target/AMD-AIE/aie/AIEX.td index 3ff90703b..a50b9b632 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEX.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEX.td @@ -12,7 +12,6 @@ #define AIEX_OPS include "AIEAttrs.td" -include "AIEInterfaces.td" include "iree-amd-aie/aie_runtime/AMDAIEEnums.td" include "mlir/IR/OpBase.td" @@ -28,7 +27,6 @@ def AIEX_Dialect : Dialect { let cppNamespace = "::xilinx::AIEX"; } - class AIEX_Op traits = []> : Op; @@ -42,9 +40,9 @@ def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator, HasParent AnyRegion:$body ); let hasCustomAssemblyFormat = 1; - let hasVerifier = 1; } +def MyOffsetSizeAndStrideOpInterface: OpInterfaceTrait<"::xilinx::AIE::MyOffsetSizeAndStrideOpInterface"> {} def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ AttrSizedOperandSegments, MyOffsetSizeAndStrideOpInterface @@ -86,8 +84,6 @@ def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ unsigned $cppClass::getOffsetSizeAndStrideStartOperandIndex() { return 1; } std::array $cppClass::getArrayAttrMaxRanks() { return {4, 4, 4}; } }]; - - let hasVerifier = 1; } def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { @@ -98,7 +94,6 @@ def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { let assemblyFormat = [{ attr-dict }]; - let hasVerifier = 1; } def AIE_NpuWriteRTPOp: AIEX_Op<"npu.rtp_write", []> { @@ -127,10 +122,6 @@ def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue", []> { let assemblyFormat = [{ `(` $column `,` $row `,` $direction `:` $channel `)` attr-dict }]; - let hasVerifier = 1; - let description = [{ - bd queue push operator - }]; } def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> { @@ -225,7 +216,6 @@ def AIE_NpuWriteBdOp: AIEX_Op<"npu.writebd", []> { ); let results = (outs ); let assemblyFormat = [{ attr-dict }]; - let hasVerifier = 1; } #endif // AIEX_OPS \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp index 9d152bdeb..10557c0ed 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp @@ -22,7 +22,6 @@ using namespace xilinx::AIE; namespace xilinx::AIEX { -// FIXME: use Tablegen'd dialect class void AIEXDialect::initialize() { addOperations< #define GET_OP_LIST @@ -87,153 +86,6 @@ int64_t AIEX::NpuDmaMemcpyNdOp::getOffsetInBytes() { return offset; } -LogicalResult AIEX::NpuDmaMemcpyNdOp::verify() { - MemRefType buffer = getMemref().getType(); - const auto &targetModel = getDeviceModel(*this); - auto addressGranularity = getAddressGenGranularity(); - auto elemWidth = buffer.getElementTypeBitWidth(); - - if (buffer.getElementTypeBitWidth() > addressGranularity) { - return emitOpError("Maximum element bit width allowed is ") - << addressGranularity << "bits. "; - } else if ((buffer.getNumElements() * buffer.getElementTypeBitWidth()) < - addressGranularity) { - return emitOpError("Minimum data transfer size required is ") - << addressGranularity << "bits. "; - } - if (!llvm::all_of(getMixedStrides(), [](OpFoldResult s) { - return getConstantIntValue(s).has_value(); - })) - return emitOpError("Only constant strides currently supported."); - if (!llvm::all_of(getMixedSizes(), [](OpFoldResult s) { - return getConstantIntValue(s).has_value(); - })) - return emitOpError("Only constant sizes currently supported."); - if (!llvm::all_of(getMixedOffsets(), [](OpFoldResult s) { - return getConstantIntValue(s).has_value(); - })) - return emitOpError("Only constant offsets currently supported."); - - llvm::SmallVector raw_strides = llvm::map_to_vector( - llvm::reverse(getMixedStrides()), - [](OpFoldResult s) { return getConstantIntValue(s).value(); }); - llvm::SmallVector raw_sizes = llvm::map_to_vector( - llvm::reverse(getMixedSizes()), - [](OpFoldResult s) { return getConstantIntValue(s).value(); }); - - llvm::SmallVector strides = getStridesInAddressGranularity(); - llvm::SmallVector sizes = getSizesInAddressGranularity(); - int64_t offset = getOffsetInBytes(); - - uint32_t wrap_bits = 0; - uint32_t step_bits = 0; - uint32_t iter_bits = 6; - if (targetModel.isShimNOCTile(getX(), getY())) { - step_bits = 20; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_STEPSIZE_WIDTH - wrap_bits = 10; // XAIEMLGBL_NOC_MODULE_DMA_BD0_3_D0_WRAP_WIDTH - } else if (targetModel.isMemTile(getX(), getY())) { - step_bits = 17; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH - wrap_bits = 10; // XAIEMLGBL_MEM_TILE_MODULE_DMA_BD0_2_D0_WRAP_WIDTH - } else if (targetModel.isCoreTile(getX(), getY())) { - step_bits = 13; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_2_D0_STEPSIZE_WIDTH - wrap_bits = 8; // XAIEMLGBL_MEMORY_MODULE_DMA_BD0_3_D0_WRAP_WIDTH - } else { - return emitOpError("Unsupported tile type at (" + std::to_string(getX()) + - ", " + std::to_string(getY()) + - ") Must be ShimNOC, Mem or Core."); - } - - if (sizes[3] > (1 << iter_bits)) - return emitOpError( - "Size 3 exceeds the [1:" + std::to_string(1 << iter_bits) + "] range."); - if (strides[2] && sizes[1] > (1 << wrap_bits) - 1) - return emitOpError("Size 1 exceeds the [0:" + - std::to_string((1 << wrap_bits) - 1) + "] range."); - if (strides[1] && sizes[0] > (1 << wrap_bits) - 1) - return emitOpError("Size 0 exceeds the [0:" + - std::to_string((1 << wrap_bits) - 1) + "] range."); - // strides[3] exceeding the range is ok iff the sizes[3] is one, which is - // checked below - if (strides[3] > (1 << step_bits) && sizes[3] != 1) - return emitOpError("Stride 3 exceeds the [1:" + - std::to_string(1 << step_bits) + "] range."); - if (strides[2] > (1 << step_bits)) - return emitOpError("Stride 2 exceeds the [1:" + - std::to_string(1 << step_bits) + "] range."); - if (strides[1] > (1 << step_bits)) - return emitOpError("Stride 1 exceeds the [1:" + - std::to_string(1 << step_bits) + "] range."); - - if (offset % 4 != 0) { - return emitOpError("Offset must be 4-byte-aligned."); - } - - for (int i = 0; i < 4; i++) { - // strides[0] == 1 is ok iff the tranfer size is a multiple of - // addressGranularity, which is checked below - if (i == 0 && raw_strides[i] == 1) continue; - if (raw_strides[i] * elemWidth % addressGranularity != 0) { - std::stringstream msg; - msg << "Stride " << i << " is " << raw_strides[i] << " elements * " - << (elemWidth / 8) << " bytes = " << (raw_strides[i] * elemWidth / 8) - << " bytes, which is not divisible by " << (addressGranularity / 8) - << ". "; - return emitOpError(msg.str()); - } - } - - if (raw_sizes[0] * elemWidth % addressGranularity != 0) { - std::stringstream msg; - msg << "Transfer sizes must be multiples of " << (addressGranularity / 8) - << " bytes. " << raw_sizes[0] << " elements at " << (elemWidth / 8) - << " bytes each equal " << (raw_sizes[0] * elemWidth / 8) - << " bytes, which is not divisible by " << (addressGranularity / 8) - << ". "; - return emitOpError(msg.str()); - } - - return success(); -} - -LogicalResult AIEX::NpuDmaWaitOp::verify() { - AIE::DeviceOp dev = (*this)->getParentOfType(); - // Some passes (e.g. aie-standard-lowering) use aiex ops outside a DeviceOp, - // so we can't expect the device to always exist. - if (dev && !dev.lookupSymbol(getSymbol())) - return emitOpError("couldn't find symbol in parent device"); - return success(); -} - -LogicalResult AIEX::NpuPushQueueOp::verify() { - const auto &targetModel = getDeviceModel(*this); - auto numBds = targetModel.getNumBDs(getColumn(), getRow()); - if (getBdId() > numBds) return emitOpError("BD ID exceeds the maximum ID."); - if (getRepeatCount() > 255) - return emitOpError("Repeat count exceeds the [0:255] range."); - return success(); -} - -LogicalResult AIEX::NpuWriteBdOp::verify() { - const auto &targetModel = getDeviceModel(*this); - auto numBds = targetModel.getNumBDs(getColumn(), getRow()); - if (getBdId() > numBds) return emitOpError("BD ID exceeds the maximum ID."); - if (getD0Size() > 0x3FF) - return emitOpError("D0 Size exceeds the [0:1023] range."); - if (getD0Stride() > 0xFFFFF) - return emitOpError("D0 Stride exceeds the [0:1M-1] range."); - if (getD1Size() > 0x3FF) - return emitOpError("D1 Size exceeds the [0:1023] range."); - if (getD1Stride() > 0xFFFFF) - return emitOpError("D1 Stride exceeds the [0:1M-1] range."); - if (getD2Stride() > 0xFFFFF) - return emitOpError("D2 Stride exceeds the [0:1M-1] range."); - if (getIterationSize() > 0x3F) - return emitOpError("Iteration Size exceeds the [0:63] range."); - if (getIterationStride() > 0xFFFFF) - return emitOpError("Iteration Stride exceeds the [0:1M-1] range."); - return success(); -} - //===----------------------------------------------------------------------===// // RuntimeSequenceOp //===----------------------------------------------------------------------===// @@ -293,22 +145,32 @@ void AIEX::RuntimeSequenceOp::print(OpAsmPrinter &printer) { printer.printRegion(body, false, true); } -LogicalResult AIEX::RuntimeSequenceOp::verify() { - AIE::DeviceOp device = (*this)->getParentOfType(); - if (!device) { - // this check is redudnant with the HasParent trait, but can't hurt - (*this)->emitOpError() << "must be inside AIE device operation."; +LogicalResult xilinx::AIE::myVerifyOffsetSizeAndStrideOp( + OffsetSizeAndStrideOpInterface op) { + std::array maxRanks = op.getArrayAttrMaxRanks(); + if (!(op.getMixedOffsets().size() == 1 && maxRanks[0] == 1) && // NOLINT + op.getMixedOffsets().size() != op.getMixedSizes().size()) + return op->emitError( + "expected mixed offsets rank to match mixed sizes rank (") + << op.getMixedOffsets().size() << " vs " << op.getMixedSizes().size() + << ") so the rank of the result type is well-formed."; + if (failed(verifyListOfOperandsOrIntegers( + op, "offset", maxRanks[0], op.getStaticOffsets(), op.getOffsets()))) return failure(); - } - auto seq_ops = device.getOps(); - if (std::distance(seq_ops.begin(), seq_ops.end()) > 1) { - auto err = device.emitOpError() - << "Cannot have more than one runtime sequence per device."; - for (auto it = seq_ops.begin(); it != seq_ops.end(); ++it) { - AIEX::RuntimeSequenceOp seq_op = *it; - err.attachNote(seq_op.getLoc()) << "Sequence operation definition here."; - } + if (failed(verifyListOfOperandsOrIntegers( + op, "size", maxRanks[1], op.getStaticSizes(), op.getSizes()))) return failure(); - } + if (failed(verifyListOfOperandsOrIntegers( + op, "stride", maxRanks[2], op.getStaticStrides(), op.getStrides()))) + return failure(); + for (int64_t offset : op.getStaticOffsets()) + if (offset < 0 && !ShapedType::isDynamic(offset)) + return op->emitError("expected offsets to be non-negative, but got ") + << offset; + for (int64_t size : op.getStaticSizes()) + if (size < 0 && !ShapedType::isDynamic(size)) + return op->emitError("expected sizes to be non-negative, but got ") + << size; + return success(); } diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h index 868e62f87..fe208803f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h @@ -13,6 +13,25 @@ #include "AIEDialect.h" +namespace xilinx::AIE { +mlir::LogicalResult +myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op); +template +struct MyOffsetSizeAndStrideOpInterfaceTrait + : public ::mlir::detail::OffsetSizeAndStrideOpInterfaceTrait { + static ::mlir::LogicalResult verifyTrait(::mlir::Operation *op) { + return myVerifyOffsetSizeAndStrideOp( + ::mlir::cast<::mlir::OffsetSizeAndStrideOpInterface>(op)); + } +}; + +struct MyOffsetSizeAndStrideOpInterface + : ::mlir::OffsetSizeAndStrideOpInterface { + template + struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait {}; +}; +} // namespace xilinx::AIE + // Include dialect declarations such as parseAttributes, parseType #include "aie/AIEXDialect.h.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt index 3bb46e08c..db5c1e449 100644 --- a/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/aie/CMakeLists.txt @@ -43,16 +43,6 @@ iree_tablegen_library( -gen-dialect-defs AIEDialect.cpp.inc ) -iree_tablegen_library( - NAME - AIEInterfacesGen - TD_FILE - AIEInterfaces.td - OUTS - -gen-op-interface-decls AIEInterfaces.h.inc - -gen-op-interface-defs AIEInterfaces.cpp.inc -) - list(APPEND IREE_COMPILER_TABLEGEN_INCLUDE_DIRS ${IREE_AMD_AIE_RUNTIME_SOURCE_DIR}) iree_tablegen_library( @@ -83,7 +73,6 @@ iree_cc_library( iree-amd-aie::aie_runtime::iree_aie_runtime_static ::AIEAttrsGen ::AIEDialectGen - ::AIEInterfacesGen ::AIEOpsGen ::AIETypesGen # mlir::DataLayout::closest(mlir::Operation*) diff --git a/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt index 58f32117e..d145d836c 100644 --- a/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt @@ -180,6 +180,10 @@ iree_cc_library( MLIRTransforms ) +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/include/air/Conversion/PassDetail.h + "aie/Dialect/AIEX/IR" "aie") + replace_string_in_file( ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIESchedulingUtils.cpp "target_model.getTargetArch()" "AIE::AIEArch::AIE2") diff --git a/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td b/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td index ec80404d2..8fd168ca1 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td +++ b/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td @@ -36,24 +36,4 @@ def DMAChannelDir: I32EnumAttr<"DMAChannelDir", let cppNamespace = "mlir::iree_compiler::AMDAIE"; } -def StrmSwPortType: I32EnumAttr<"StrmSwPortType", "", - [ - I32EnumAttrCase<"CORE", 0>, - I32EnumAttrCase<"DMA", 1>, - I32EnumAttrCase<"CTRL", 2>, - I32EnumAttrCase<"FIFO", 3>, - I32EnumAttrCase<"SOUTH", 4>, - I32EnumAttrCase<"WEST", 5>, - I32EnumAttrCase<"NORTH", 6>, - I32EnumAttrCase<"EAST", 7>, - I32EnumAttrCase<"TRACE", 8>, - I32EnumAttrCase<"UCTRLR", 9>, - I32EnumAttrCase<"SS_PORT_TYPE_MAX", 10>, - // "illegal" types after max - I32EnumAttrCase<"NOC", 11> - ]> -{ - let cppNamespace = "mlir::iree_compiler::AMDAIE"; -} - #endif // IREE_AIE_RUNTIME_AMDAIEENUMS diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc index 22b9a5bf7..0dd0f4d06 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc @@ -79,6 +79,13 @@ bool isAieRtCompatStrmSwPortType( ::StrmSwPortType checkedAieRtCompatStrmSwPortType( mlir::iree_compiler::AMDAIE::StrmSwPortType t, const char *file, unsigned int line, const char *function) { +#ifndef NDEBUG + if (!isAieRtCompatStrmSwPortType(t)) { + llvm::report_fatal_error(llvm::formatv( + "{0}:{1}:{2}: StrmSwPortType incompatible with aie-rt: {3}", file, + line, function, to_string(t))); + } +#endif return static_cast<::StrmSwPortType>(t); } // macro so that line numbers are preserved for where the check fails @@ -89,8 +96,7 @@ ::StrmSwPortType checkedAieRtCompatStrmSwPortType( namespace mlir::iree_compiler::AMDAIE { -::mlir::iree_compiler::AMDAIE::StrmSwPortType getConnectingBundle( - StrmSwPortType dir) { +StrmSwPortType getConnectingBundle(StrmSwPortType dir) { switch (dir) { case StrmSwPortType::NORTH: return StrmSwPortType::SOUTH; @@ -434,6 +440,12 @@ uint32_t AMDAIEDeviceModel::getNumDestSwitchBoxConnections( return strmMod->MstrConfig[CheckedAieRtCompatStrmSwPortType(bundle)].NumPorts; } +uint32_t AMDAIEDeviceModel::getNumDestSwitchboxConnections( + int col, int row, StrmSwPortType bundle) const { + return getNumDestSwitchboxConnections(static_cast(col), + static_cast(row), bundle); +} + uint32_t AMDAIEDeviceModel::getColumnShift() const { return configPtr.ColShift; } diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h index 1f1b98c6d..b8879147d 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h @@ -134,19 +134,29 @@ enum class AMDAIEDmaBdProp : uint8_t { MAX = sizeof(XAie_DmaBdProp) }; -static_assert( - static_cast(::mlir::iree_compiler::AMDAIE::StrmSwPortType::CORE) == - ::StrmSwPortType::CORE, - "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " - "aie-rt's StrmSwPortType"); -static_assert( - static_cast( - ::mlir::iree_compiler::AMDAIE::StrmSwPortType::SS_PORT_TYPE_MAX) == - ::StrmSwPortType::SS_PORT_TYPE_MAX, - "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " - "aie-rt's StrmSwPortType"); -inline ::StrmSwPortType strmTtoStrmT( - ::mlir::iree_compiler::AMDAIE::StrmSwPortType t) { +enum class StrmSwPortType : uint8_t { + CORE = ::StrmSwPortType::CORE, + DMA, + CTRL, + FIFO, + SOUTH, + WEST, + NORTH, + EAST, + TRACE, + UCTRLR, + SS_PORT_TYPE_MAX, + // "illegal" types after max + NOC, +}; +static_assert(static_cast(StrmSwPortType::CORE) == 0, + "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " + "aie-rt's StrmSwPortType"); +static_assert(static_cast(StrmSwPortType::SS_PORT_TYPE_MAX) == + ::StrmSwPortType::SS_PORT_TYPE_MAX, + "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " + "aie-rt's StrmSwPortType"); +inline ::StrmSwPortType strmTtoStrmT(StrmSwPortType t) { return static_cast<::StrmSwPortType>(t); } @@ -279,38 +289,32 @@ struct AMDAIEDeviceModel { uint32_t getNumBDs(uint8_t col, uint8_t row) const; - uint32_t getNumSourceSwitchBoxConnections( - uint8_t col, uint8_t row, - ::mlir::iree_compiler::AMDAIE::StrmSwPortType bundle) const; - uint32_t getNumDestSwitchBoxConnections( - uint8_t col, uint8_t row, - ::mlir::iree_compiler::AMDAIE::StrmSwPortType bundle) const; - bool isLegalTileConnection( - uint8_t col, uint8_t row, - ::mlir::iree_compiler::AMDAIE::StrmSwPortType srcBundle, uint8_t srcChan, - ::mlir::iree_compiler::AMDAIE::StrmSwPortType dstBundle, - uint8_t dstChan) const; + uint32_t getNumSourceSwitchBoxConnections(uint8_t col, uint8_t row, + StrmSwPortType bundle) const; + uint32_t getNumDestSwitchBoxConnections(uint8_t col, uint8_t row, + StrmSwPortType bundle) const; + bool isLegalTileConnection(uint8_t col, uint8_t row, StrmSwPortType srcBundle, + uint8_t srcChan, StrmSwPortType dstBundle, + uint8_t dstChan) const; uint32_t getColumnShift() const; uint32_t getRowShift() const; - // mlir-air legacy - uint32_t getNumDestSwitchboxConnections( - int col, int row, - ::mlir::iree_compiler::AMDAIE::StrmSwPortType bundle) const; - uint32_t getNumMemTileRows() const { return 1; } - /// Return a map from channels to valid BD ids for the requested tile type. /// TODO(jornt): find these ranges in the device model. DenseMap> getChannelToValidBdIds( AMDAIETileType tileType) const; AMDAIEDevice device; + + // mlir-air legacy + uint32_t getNumDestSwitchboxConnections(int col, int row, + StrmSwPortType bundle) const; + uint32_t getNumMemTileRows() const { return 1; } }; struct AMDAIEDeviceModel getDeviceModel(AMDAIEDevice device); -::mlir::iree_compiler::AMDAIE::StrmSwPortType getConnectingBundle( - ::mlir::iree_compiler::AMDAIE::StrmSwPortType dir); +StrmSwPortType getConnectingBundle(StrmSwPortType dir); bool isNPUDevice(mlir::iree_compiler::AMDAIE::AMDAIEDevice d); /// ============================= BEGIN ================================== From 9fafe3930baa8a2c834af805977d7656eba5a652 Mon Sep 17 00:00:00 2001 From: max Date: Tue, 6 Aug 2024 14:18:24 -0500 Subject: [PATCH 09/12] update tests --- compiler/plugins/target/AMD-AIE/aie/AIE.td | 18 +- .../plugins/target/AMD-AIE/aie/AIEAttrs.td | 54 +- .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 29 +- .../plugins/target/AMD-AIE/aie/AIEDialect.h | 77 +- .../plugins/target/AMD-AIE/aie/AIEEnums.h | 8 +- .../AMD-AIE/aie/AIENormalizeAddressSpaces.td | 8 +- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 75 +- .../plugins/target/AMD-AIE/aie/AIETypes.td | 16 +- compiler/plugins/target/AMD-AIE/aie/AIEX.td | 8 +- .../target/AMD-AIE/aie/AIEXDialect.cpp | 8 +- .../plugins/target/AMD-AIE/aie/AIEXDialect.h | 16 +- .../AMD-AIE/aie/AMDAIEAssignLockIDs.cpp | 2 +- .../aie/AMDAIEObjectFifoStatefulTransform.cpp | 4 +- .../aie/test/AIE2_cyclostatic_dma.mlir | 8 +- .../AMD-AIE/aie/test/AIE2_cyclostatic_l1.mlir | 4 +- .../AMD-AIE/aie/test/AIE2_cyclostatic_l2.mlir | 12 +- .../aie/test/AIE2_delayed_release.mlir | 4 +- .../AMD-AIE/aie/test/AIE2_static_l1.mlir | 4 +- .../aie/test/aie2_memtile_connection.mlir | 18 +- .../aie/test/allocation_info_test.mlir | 32 +- .../target/AMD-AIE/aie/test/bad_npu_nd.mlir | 211 -- .../AMD-AIE/aie/test/base_test_AIE1.mlir | 12 +- .../AMD-AIE/aie/test/base_test_AIE2.mlir | 12 +- .../target/AMD-AIE/aie/test/basic.mlir | 8 +- .../AMD-AIE/aie/test/broadcast_test.mlir | 20 +- .../aie/test/circuit_and_packet_routing.mlir | 4 +- .../aie/test/cyclostatic_AIE2_sharedMem.mlir | 4 +- .../AMD-AIE/aie/test/link_test_AIE1.mlir | 12 +- .../AMD-AIE/aie/test/link_test_AIE2.mlir | 16 +- .../AMD-AIE/aie/test/link_test_DDR_to_L1.mlir | 12 +- .../AMD-AIE/aie/test/link_test_L1_to_DDR.mlir | 12 +- .../AMD-AIE/aie/test/link_test_broadcast.mlir | 24 +- .../aie/test/link_test_distribute.mlir | 20 +- .../AMD-AIE/aie/test/link_test_join.mlir | 24 +- .../AMD-AIE/aie/test/loop_test.aie.mlir | 4 +- .../AMD-AIE/aie/test/loop_test_nested.mlir | 4 +- .../target/AMD-AIE/aie/test/lower_dma.mlir | 8 +- .../target/AMD-AIE/aie/test/matmul_test.mlir | 24 +- .../target/AMD-AIE/aie/test/memTile_test.mlir | 8 +- .../AMD-AIE/aie/test/nd_dma_base_AIE2.mlir | 16 +- .../aie/test/nd_dma_distribute_AIE2.mlir | 16 +- .../test/nd_dma_multiple_consumers_AIE2.mlir | 28 +- .../AMD-AIE/aie/test/nested_loop_test.mlir | 28 +- .../aie/test/non_adjacency_test_1.mlir | 8 +- .../aie/test/non_adjacency_test_2.mlir | 8 +- .../aie/test/non_adjacency_test_AIE2.mlir | 8 +- .../test/packet_routing_keep_pkt_header.mlir | 8 +- .../test/register_external_buffers_test.mlir | 8 +- .../same_core_producer_consumer_test.mlir | 4 +- .../AMD-AIE/aie/test/shimRow_mem_test.mlir | 8 +- .../AMD-AIE/aie/test/shim_AIE2_test.mlir | 16 +- .../AMD-AIE/aie/test/shim_broadcast_test.mlir | 16 +- .../AMD-AIE/aie/test/subview_test_1.mlir | 4 +- .../AMD-AIE/aie/test/subview_test_2.mlir | 8 +- .../AMD-AIE/aie/test/subview_test_3.mlir | 10 +- .../AMD-AIE/aie/test/test_congestion0.mlir | 16 +- .../AMD-AIE/aie/test/test_congestion1.mlir | 42 +- .../aie/test/test_create_packet_flows0.mlir | 14 +- .../aie/test/test_create_packet_flows1.mlir | 14 +- .../aie/test/test_create_packet_flows2.mlir | 26 +- .../aie/test/test_create_packet_flows3.mlir | 28 +- .../aie/test/test_create_packet_flows4.mlir | 20 +- .../aie/test/test_create_packet_flows5.mlir | 18 +- .../aie/test/test_create_packet_flows6.mlir | 16 +- .../test/test_create_packet_flows_shim0.mlir | 8 +- .../test/test_create_packet_flows_shim1.mlir | 8 +- .../aie/test/test_pktflow_weight_pusher.mlir | 78 +- .../target/AMD-AIE/aie/test/tileDMA_test.mlir | 8 +- .../aie/test/trace_packet_routing.mlir | 4 +- .../AMD-AIE/aie/test/unit_broadcast.mlir | 88 +- .../aie/test/unit_fixed_connections.mlir | 136 +- .../AMD-AIE/aie/test/unit_flow_test_1.mlir | 356 ++-- .../AMD-AIE/aie/test/unit_flow_test_2.mlir | 192 +- .../AMD-AIE/aie/test/unit_flow_test_3.mlir | 364 ++-- .../AMD-AIE/aie/test/unit_many_flows.mlir | 194 +- .../AMD-AIE/aie/test/unit_many_flows2.mlir | 168 +- .../target/AMD-AIE/aie/test/unit_memtile.mlir | 56 +- .../unit_memtile_routing_constraints.mlir | 14 +- .../target/AMD-AIE/aie/test/unit_mmult.mlir | 300 +-- .../AMD-AIE/aie/test/unit_over_flows.mlir | 112 +- .../aie/test/unit_routed_herd_3x1.mlir | 390 ++-- .../aie/test/unit_routed_herd_3x2.mlir | 206 +- .../target/AMD-AIE/aie/test/unit_simple.mlir | 16 +- .../target/AMD-AIE/aie/test/unit_simple2.mlir | 8 +- .../AMD-AIE/aie/test/unit_simple_flows.mlir | 16 +- .../AMD-AIE/aie/test/unit_simple_flows2.mlir | 14 +- .../aie/test/unit_simple_flows_shim.mlir | 16 +- .../AMD-AIE/aie/test/unit_vecmul_4x4.mlir | 1776 ++++++++--------- .../AMD-AIE/aie/test/user_assigned.mlir | 8 +- .../plugins/target/AMD-AIE/air/CMakeLists.txt | 22 +- .../AMDAIEDistributeCoresAndObjectFifos.cpp | 6 +- .../iree-amd-aie/aie_runtime/AMDAIEEnums.td | 22 +- .../aie_runtime/iree_aie_runtime.cc | 4 +- .../aie_runtime/iree_aie_runtime.h | 28 +- ...dd_12_i8_using_2d_dma_op_with_padding.mlir | 4 +- .../add_21_i8_using_dma_op_with_padding.mlir | 4 +- ...add_378_i32_using_dma_op_with_padding.mlir | 4 +- ...8xi32__dispatch_0_matmul_16x1_0.aiecc.mlir | 66 +- ...32xi8__dispatch_0_matmul_tran_0.aiecc.mlir | 66 +- ...2_512xi32__dispatch_0_matmul__0.aiecc.mlir | 628 +++--- ...64xbf16__dispatch_0_matmul_64_0.aiecc.mlir | 66 +- ...64xi8__dispatch_0_matmul_64x6_0.aiecc.mlir | 66 +- ...6xi32__dispatch_0_matmul_8x32_0.aiecc.mlir | 66 +- 103 files changed, 3321 insertions(+), 3499 deletions(-) delete mode 100644 compiler/plugins/target/AMD-AIE/aie/test/bad_npu_nd.mlir diff --git a/compiler/plugins/target/AMD-AIE/aie/AIE.td b/compiler/plugins/target/AMD-AIE/aie/AIE.td index b9fbc9ef3..9b674418f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIE.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIE.td @@ -1,12 +1,8 @@ -//===- AIE.td ----------------------------------------------*- tablegen -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef AIE_BASE #define AIE_BASE @@ -16,16 +12,6 @@ include "mlir/IR/OpBase.td" def AIE_Dialect : Dialect { let name = "aie"; let cppNamespace = "::xilinx::AIE"; - let description = [{ - - This is a dialect for describing netlists of AIE components in a - Versal device. It focuses on representing logical stream connections - between cores and DMAs, along with the implementation of those logical - connections in the various switch components. In the dialect, a - switch is referred to as `switchbox` to avoid confusion with the - `switch` keyword in C/C++. - - }]; let useDefaultTypePrinterParser = 1; let useDefaultAttributePrinterParser = 1; } diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td index e739099f1..ebcfcad18 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td @@ -1,12 +1,8 @@ -//===- AIEAttrs.td -----------------------------------------*- tablegen -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef AIE_ATTRS #define AIE_ATTRS @@ -16,10 +12,6 @@ include "AIE.td" include "mlir/IR/AttrTypeBase.td" include "mlir/IR/EnumAttr.td" -//===----------------------------------------------------------------------===// -// AIE attributes. -//===----------------------------------------------------------------------===// - def LockAction: I32EnumAttr<"LockAction", "lock acquire/release", [ I32EnumAttrCase<"Acquire", 0>, @@ -39,30 +31,6 @@ def LockBlocking: I32EnumAttr<"LockBlocking", "lock operation is blocking", let cppNamespace = "xilinx::AIE"; } -def AIEArch: I32EnumAttr<"AIEArch", "AIE Architecture", - [ - I32EnumAttrCase<"AIE1", 1>, - I32EnumAttrCase<"AIE2", 2> - ]> { - - let cppNamespace = "xilinx::AIE"; -} - -def AIEDevice: I32EnumAttr<"AIEDevice", "AIE Device", - [ - I32EnumAttrCase<"xcvc1902", 1>, - I32EnumAttrCase<"xcve2302", 2>, - I32EnumAttrCase<"xcve2802", 3>, - I32EnumAttrCase<"npu1", 4>, - I32EnumAttrCase<"npu1_1col", 5>, - I32EnumAttrCase<"npu1_2col", 6>, - I32EnumAttrCase<"npu1_3col", 7>, - I32EnumAttrCase<"npu1_4col", 8> - ]> { - - let cppNamespace = "xilinx::AIE"; -} - def ObjectFifoPort: I32EnumAttr<"ObjectFifoPort", "Ports of an object FIFO", [ @@ -75,11 +43,6 @@ def ObjectFifoPort: I32EnumAttr<"ObjectFifoPort", def BDDimLayoutAttr : AttrDef { let mnemonic = "bd_dim_layout"; - let summary = [{ - Tuple encoding the stride and size of one dimension in an AIE2 n-dimensional - buffer descriptor; - }]; - let parameters = (ins "uint16_t" : $size, "uint32_t" : $stride @@ -104,11 +67,6 @@ def BDDimLayoutArrayArrayAttr : ArrayOfAttr< def BDPadLayoutAttr : AttrDef { let mnemonic = "bd_pad_layout"; - let summary = [{ - Tuple encoding number of zeros before and after on that dimension in an AIE2 - n-dimensional buffer descriptor; - }]; - let parameters = (ins "uint16_t" : $const_pad_before, "uint16_t" : $const_pad_after @@ -124,12 +82,4 @@ def BDPadLayoutArrayAttr : ArrayOfAttr< /*eltName*/BDPadLayoutAttr.cppClassName >; -def StrmSwPortTypeAttr : Attr, ""> { - let storageType = [{ ::mlir::IntegerAttr }]; - let returnType = [{ ::mlir::iree_compiler::AMDAIE::StrmSwPortType }]; - let valueType = I32; - let constBuilderCall = "$_builder.getI32IntegerAttr(static_cast($0))"; - code convertFromStorage = "::mlir::iree_compiler::AMDAIE::StrmSwPortType($_self.getValue().getZExtValue())"; -} - #endif // AIE_ATTRS \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index 0c367a0ff..1d5cea379 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -1,20 +1,13 @@ -//===- AIEDialect.cpp -------------------------------------------*- C++ -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #include "AIEDialect.h" #include "llvm/ADT/DenseSet.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/TypeSwitch.h" -#include "mlir/Dialect/Func/IR/FuncOps.h" -#include "mlir/Dialect/MemRef/IR/MemRef.h" #include "mlir/IR/DialectImplementation.h" #include "mlir/IR/OpDefinition.h" #include "mlir/Interfaces/FoldInterfaces.h" @@ -23,8 +16,6 @@ using namespace mlir; using namespace xilinx::AIE; -// Add TableGen'erated dialect definitions (including constructor) -// We implement the initialize() function further below #include "aie/AIEDialect.cpp.inc" namespace xilinx::AIE { @@ -159,6 +150,20 @@ void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { } } +// without this, canonicalize/cse/etc will lift eg constants out of core ops +// causing eg lower-to-aie to fail to converge +struct AIEDialectFoldInterface : DialectFoldInterface { + using DialectFoldInterface::DialectFoldInterface; + + /// Registered hook to check if the given region, which is attached to an + /// operation that is *not* isolated from above, should be used when + /// materializing constants. + bool shouldMaterializeInto(Region *region) const final override { + // If this is an AIE::CoreOp region, then insert into it. + return isa(region->getParentOp()); + } +}; + void AIEDialect::initialize() { addTypes(); addAttributes< @@ -169,11 +174,11 @@ void AIEDialect::initialize() { #define GET_OP_LIST #include "aie/AIEOps.cpp.inc" >(); + addInterfaces(); } } // namespace xilinx::AIE #include "aie/AIEEnums.cpp.inc" -#include "aie/AIEInterfaces.cpp.inc" #define GET_OP_CLASSES #include "aie/AIEOps.cpp.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index 9b31c18e6..ec1caf38a 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -1,12 +1,8 @@ -//===- AIEDialect.h ---------------------------------------------*- C++ -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef MLIR_AIE_DIALECT_H #define MLIR_AIE_DIALECT_H @@ -75,10 +71,21 @@ using DMAChannelDir = mlir::iree_compiler::AMDAIE::DMAChannelDir; using Port = mlir::iree_compiler::AMDAIE::Port; using WireBundle = mlir::iree_compiler::AMDAIE::StrmSwPortType; using DMAChannelDirAttr = mlir::iree_compiler::AMDAIE::DMAChannelDirAttr; -// using DMAChannel = mlir::iree_compiler::AMDAIE::DMAChannel; +using AIEArch = mlir::iree_compiler::AMDAIE::AIEArch; +using AIEDevice = mlir::iree_compiler::AMDAIE::AMDAIEDevice; +using AIEDeviceAttr = mlir::iree_compiler::AMDAIE::AMDAIEDeviceAttr; + +inline std::optional +symbolizeAIEDevice(uint32_t d) { + return mlir::iree_compiler::AMDAIE::symbolizeAMDAIEDevice(d); +} + +inline std::optional +symbolizeAIEDevice(llvm::StringRef d) { + return mlir::iree_compiler::AMDAIE::symbolizeAMDAIEDevice(d); +} } // namespace xilinx::AIE -// Include dialect declarations such as parseAttributes, parseType #include "aie/AIEDialect.h.inc" #define GET_ATTRDEF_CLASSES @@ -281,6 +288,60 @@ inline bool TileOp::isMemTile() { return deviceModel.isMemTile(this->getCol(), this->getRow()); } +template +inline void getAsmResultNames( + T op, llvm::function_ref setNameFn) { + std::string nameWithoutDialect = + op->getOperationName().str().substr(op->getOperationName().find('.') + 1); + auto t = llvm::cast(op->getTile().getDefiningOp()); + setNameFn(op->getResult(), nameWithoutDialect + "_" + + std::to_string(t.getCol()) + "_" + + std::to_string(t.getRow())); +} + +inline void SwitchboxOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void ShimMuxOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void MemOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void CoreOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void MemTileDMAOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void BufferOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void LockOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +inline void TileOp::getAsmResultNames( + llvm::function_ref setNameFn) { + std::string nameWithoutDialect = + getOperationName().str().substr(getOperationName().find('.') + 1); + setNameFn(getResult(), nameWithoutDialect + "_" + std::to_string(getCol()) + + "_" + std::to_string(getRow())); +} + inline mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel DeviceOp::getTargetModel() { return getDeviceModel(this->getOperation()); diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h b/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h index caa255f83..7e6dbe508 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h @@ -1,12 +1,8 @@ -//===- AIEEnums.h -----------------------------------------------*- C++ -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 Advanced Micro Devices, Inc. -// -//===----------------------------------------------------------------------===// #ifndef MLIR_AIE_ENUMS_H #define MLIR_AIE_ENUMS_H diff --git a/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td b/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td index 378fec3ba..8c1ece08d 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIENormalizeAddressSpaces.td @@ -1,12 +1,8 @@ -//===- AIENormalizeAddressSpaces.td ------------------------*- tablegen -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2021 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef AIE_NORMALIZE_ADDRESS_SPACES #define AIE_NORMALIZE_ADDRESS_SPACES diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index e538be920..3862babc3 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -1,12 +1,8 @@ -//===- AIE.td ----------------------------------------------*- tablegen -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef AIE_OPS #define AIE_OPS @@ -21,6 +17,7 @@ include "mlir/IR/SymbolInterfaces.td" include "mlir/Interfaces/CallInterfaces.td" include "mlir/Interfaces/InferTypeOpInterface.td" include "mlir/Interfaces/SideEffectInterfaces.td" +include "mlir/IR/OpAsmInterface.td" class AIE_Op traits = []> : Op; @@ -31,7 +28,7 @@ def AIE_DeviceOp: AIE_Op<"device", [ SymbolTable, SingleBlock, NoTerminator, IsolatedFromAbove ]> { let summary = "Define an AIE design targetting a complete device"; - let arguments = (ins AIEDevice:$device); + let arguments = (ins AMDAIEDeviceAttr:$device); let regions = (region AnyRegion:$body_region); let assemblyFormat = [{ `(` $device `)` regions attr-dict @@ -45,6 +42,7 @@ def AIE_DeviceOp: AIE_Op<"device", [ def AIE_TileOp: AIE_Op<"tile", [ Pure, + DeclareOpInterfaceMethods, DeclareOpInterfaceMethods ]>, Results<(outs Index:$result)> { let arguments = ( @@ -67,6 +65,8 @@ def AIE_TileOp: AIE_Op<"tile", [ MemOp getMemOp(); size_t getNumSourceConnections(mlir::iree_compiler::AMDAIE::StrmSwPortType w); size_t getNumDestConnections(mlir::iree_compiler::AMDAIE::StrmSwPortType w); + void getAsmResultNames( + llvm::function_ref setNameFn); }]; } @@ -76,6 +76,7 @@ def AIE_EndOp: AIE_Op<"end", [Terminator]> { } def AIE_SwitchboxOp: AIE_Op<"switchbox", [ + DeclareOpInterfaceMethods, SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index:$result)> { @@ -84,6 +85,11 @@ def AIE_SwitchboxOp: AIE_Op<"switchbox", [ let summary = "Declare a switch"; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + // mlir-air legacy + let extraClassDeclaration = [{ + void getAsmResultNames( + llvm::function_ref setNameFn); + }]; } def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ @@ -97,6 +103,7 @@ def AIE_ShimSwitchboxOp: AIE_Op<"shim_switchbox", [ } def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ + DeclareOpInterfaceMethods, SingleBlockImplicitTerminator<"EndOp">, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { @@ -106,9 +113,14 @@ def AIE_ShimMuxOp: AIE_Op<"shim_mux", [ let summary = "Declare a switch in the PL shim"; let regions = (region AnyRegion:$connections); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let extraClassDeclaration = [{ + void getAsmResultNames( + llvm::function_ref setNameFn); + }]; } def AIE_CoreOp: AIE_Op<"core", [ + DeclareOpInterfaceMethods, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let arguments = ( @@ -129,6 +141,8 @@ def AIE_CoreOp: AIE_Op<"core", [ // mlir-air legacy let extraClassDeclaration = [{ TileOp getTileOp(); + void getAsmResultNames( + llvm::function_ref setNameFn); }]; } @@ -283,6 +297,7 @@ def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { } def AIE_DMABDOp: AIE_Op<"dma_bd", [ + DeclareOpInterfaceMethods, ParentOneOf<["MemOp", "MemTileDMAOp"]>, ]> { let summary = "Declare a dma buffer descriptor op"; @@ -355,21 +370,33 @@ def AIE_DMAStartOp: AIE_Op<"dma_start", [ // 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", [ + DeclareOpInterfaceMethods, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a memory op"; let arguments = (ins Index:$tile); let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + // mlir-air legacy + let extraClassDeclaration = [{ + void getAsmResultNames( + llvm::function_ref setNameFn); + }]; } def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ + DeclareOpInterfaceMethods, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a memtile_dma op"; let arguments = (ins Index:$tile); let regions = (region AnyRegion:$body); let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + // mlir-air legacy + let extraClassDeclaration = [{ + void getAsmResultNames( + llvm::function_ref setNameFn); + }]; } def AIE_NextBDOp: AIE_Op<"next_bd", [ @@ -384,14 +411,15 @@ def AIE_NextBDOp: AIE_Op<"next_bd", [ } def AIE_LockOp: AIE_Op<"lock", [ + DeclareOpInterfaceMethods, Pure, DeclareOpInterfaceMethods ]>, Results<(outs Index)> { let summary = "Declare a physical lock"; let arguments = ( ins Index:$tile, - OptionalAttr]>>:$lockID, - OptionalAttr:$init, - OptionalAttr:$sym_name + OptionalAttr]>>:$lockID, + OptionalAttr:$init, + OptionalAttr:$sym_name ); let assemblyFormat = [{ `(` $tile (`,` $lockID^ )? `)` attr-dict }]; @@ -413,6 +441,8 @@ def AIE_LockOp: AIE_Op<"lock", [ assert(getLockID().has_value() && "Lock has no ID value"); return getLockID().value(); } + void getAsmResultNames( + llvm::function_ref setNameFn); }]; } @@ -439,7 +469,9 @@ def AIE_UseLockOp: AIE_Op<"use_lock", []> { ]; } -def AIE_BufferOp: AIE_Op<"buffer", []>, Results<(outs AnyMemRef)> { +def AIE_BufferOp: AIE_Op<"buffer", [ + DeclareOpInterfaceMethods, +]>, Results<(outs AnyMemRef)> { let summary = "Declare a buffer"; let arguments = ( ins Index:$tile, @@ -455,6 +487,8 @@ def AIE_BufferOp: AIE_Op<"buffer", []>, Results<(outs AnyMemRef)> { // mlir-air legacy let extraClassDeclaration = [{ TileOp getTileOp(); + void getAsmResultNames( + llvm::function_ref setNameFn); }]; } @@ -463,8 +497,8 @@ def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp let arguments = ( ins FlatSymbolRefAttr:$sym_name, DMAChannelDir:$channel_dir, - I8Attr:$channel_index, - I8Attr:$col, + I64Attr:$channel_index, + I64Attr:$col, // If this is set we are using the PLIO in this ShimTile DefaultValuedAttr:$plio ); @@ -538,7 +572,6 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { let assemblyFormat = [{ $fifoIns `->` $fifoOuts `(` `)` attr-dict }]; - } def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { @@ -617,5 +650,19 @@ def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ }]; } +// legacy tests + +def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_external_buffers"> { + let summary = "Registers external buffers to given object fifo shim tile(s) to use in the associated shim DMA(s)"; + let arguments = ( + ins FlatSymbolRefAttr:$objFifo_name, + Index:$tile, + Variadic:$externalBuffers + ); + + let assemblyFormat = [{ + attr-dict $objFifo_name `(` $tile `,` `{` $externalBuffers `}` `)` `:` `(` type($externalBuffers) `)` + }]; +} #endif // AIE_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td index e08ee4fc1..33e68dde1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td @@ -1,18 +1,14 @@ -//===- AIETypes.td -----------------------------------------*- tablegen -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef AIE_TYPES #define AIE_TYPES -include "aie/Dialect/AIE/IR/AIE.td" -include "aie/Dialect/AIE/IR/AIEAttrs.td" +include "AIE.td" +include "AIEAttrs.td" include "mlir/IR/AttrTypeBase.td" @@ -24,8 +20,4 @@ def AIE_ObjectFifoSubviewType : DialectType($_self)">, "AIE ObjectFifoSubview type">; -def StrmSwPortType : DialectType, "">, - BuildableType<"::mlir::iree_compiler::AMDAIE::StrmSwPortType{}">; - #endif // AIE_TYPES \ No newline at end of file diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEX.td b/compiler/plugins/target/AMD-AIE/aie/AIEX.td index a50b9b632..61d916424 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEX.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEX.td @@ -1,12 +1,8 @@ -//===- AIE.td ----------------------------------------------*- tablegen -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef AIEX_OPS #define AIEX_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp index 10557c0ed..dcd4d417a 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp @@ -1,12 +1,8 @@ -//===- AIEXDialect.cpp ------------------------------------------*- C++ -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #include "AIEXDialect.h" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h index fe208803f..445f42eec 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.h @@ -1,12 +1,8 @@ -//===- AIEDialect.h ---------------------------------------------*- C++ -*-===// +// Copyright 2024 The IREE Authors // -// This file is licensed under the Apache License v2.0 with LLVM Exceptions. +// 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 2019 Xilinx Inc. -// -//===----------------------------------------------------------------------===// #ifndef MLIR_AIEX_DIALECT_H #define MLIR_AIEX_DIALECT_H @@ -14,8 +10,8 @@ #include "AIEDialect.h" namespace xilinx::AIE { -mlir::LogicalResult -myVerifyOffsetSizeAndStrideOp(mlir::OffsetSizeAndStrideOpInterface op); +mlir::LogicalResult myVerifyOffsetSizeAndStrideOp( + mlir::OffsetSizeAndStrideOpInterface op); template struct MyOffsetSizeAndStrideOpInterfaceTrait : public ::mlir::detail::OffsetSizeAndStrideOpInterfaceTrait { @@ -30,12 +26,10 @@ struct MyOffsetSizeAndStrideOpInterface template struct Trait : public MyOffsetSizeAndStrideOpInterfaceTrait {}; }; -} // namespace xilinx::AIE +} // namespace xilinx::AIE -// Include dialect declarations such as parseAttributes, parseType #include "aie/AIEXDialect.h.inc" -// include TableGen generated Op definitions #define GET_OP_CLASSES #include "aie/AIEX.h.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp index 5636c2079..3d6efe6fc 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEAssignLockIDs.cpp @@ -100,7 +100,7 @@ struct AMDAIEAssignLockIDsPass : mlir::OperationPass { << " locks available in this tile."; return signalPassFailure(); } - lockOp.setLockIDAttr(rewriter.getI32IntegerAttr(nextID)); + lockOp.setLockIDAttr(rewriter.getI8IntegerAttr(nextID)); ++nextID; } } diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp index b352697f7..af73621ad 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEObjectFifoStatefulTransform.cpp @@ -164,8 +164,8 @@ class LockAnalysis { }; class DMAChannelAnalysis { - DenseMap producerChannelsPerTile; - DenseMap consumerChannelsPerTile; + DenseMap producerChannelsPerTile; + DenseMap consumerChannelsPerTile; public: DMAChannelAnalysis(DeviceOp &device) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_dma.mlir b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_dma.mlir index 5cf17dbba..1a1fa1e51 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_dma.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_dma.mlir @@ -9,12 +9,12 @@ // CHECK: %[[FIFO_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "fifo_cons_buff_0"} : memref // CHECK: %[[FIFO_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "fifo_cons_buff_1"} : memref // CHECK: %[[FIFO_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "fifo_cons_buff_2"} : memref -// CHECK: %[[FIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 0) {init = 3 : i32, sym_name = "fifo_cons_prod_lock"} -// CHECK: %[[FIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 1) {init = 0 : i32, sym_name = "fifo_cons_cons_lock"} +// CHECK: %[[FIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 0) {init = 3 : i8, sym_name = "fifo_cons_prod_lock"} +// CHECK: %[[FIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 1) {init = 0 : i8, sym_name = "fifo_cons_cons_lock"} // CHECK: %[[FIFO_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_0"} : memref // CHECK: %[[FIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_1"} : memref -// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "fifo_prod_lock"} -// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "fifo_cons_lock"} +// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "fifo_prod_lock"} +// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "fifo_cons_lock"} // CHECK: %[[BUF83:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "buf83"} : memref<4xi32> // CHECK: aie.flow(%[[TILE_2_2]], DMA : 0, %[[TILE_8_3]], DMA : 0) // CHECK: %[[CORE_2_2:.*]] = aie.core(%[[TILE_2_2]]) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l1.mlir index 8d57fc533..6b4c7c694 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l1.mlir @@ -9,8 +9,8 @@ // CHECK: %[[FIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_1"} : memref // CHECK: %[[FIFO_BUFF_2:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_2"} : memref // CHECK: %[[FIFO_BUFF_3:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_3"} : memref -// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 4 : i32, sym_name = "fifo_prod_lock"} -// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "fifo_cons_lock"} +// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 4 : i8, sym_name = "fifo_prod_lock"} +// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "fifo_cons_lock"} // CHECK: %[[BUF23:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "buf23"} : memref<4xi32> // CHECK: %[[CORE_2_2:.*]] = aie.core(%[[TILE_2_2]]) { // CHECK: %[[C55_I32:.*]] = arith.constant 55 : i32 diff --git a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l2.mlir index df556aff9..da66f23e1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_cyclostatic_l2.mlir @@ -13,18 +13,18 @@ // CHECK: %[[FIFO1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "fifo1_cons_buff_1"} : memref<1xi32> // CHECK: %[[FIFO1_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "fifo1_cons_buff_2"} : memref<1xi32> // CHECK: %[[FIFO1_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "fifo1_cons_buff_3"} : memref<1xi32> -// CHECK: %[[FIFO1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 0) {init = 4 : i32, sym_name = "fifo1_cons_prod_lock"} -// CHECK: %[[FIFO1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 1) {init = 0 : i32, sym_name = "fifo1_cons_cons_lock"} +// CHECK: %[[FIFO1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 0) {init = 4 : i8, sym_name = "fifo1_cons_prod_lock"} +// CHECK: %[[FIFO1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_8_3]], 1) {init = 0 : i8, sym_name = "fifo1_cons_cons_lock"} // CHECK: %[[FIFO0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "fifo0_cons_buff_0"} : memref<1xi32> // CHECK: %[[FIFO0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "fifo0_cons_buff_1"} : memref<1xi32> // CHECK: %[[FIFO0_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "fifo0_cons_buff_2"} : memref<1xi32> // CHECK: %[[FIFO0_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "fifo0_cons_buff_3"} : memref<1xi32> -// CHECK: %[[FIFO0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 4 : i32, sym_name = "fifo0_cons_prod_lock"} -// CHECK: %[[FIFO0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "fifo0_cons_cons_lock"} +// CHECK: %[[FIFO0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 4 : i8, sym_name = "fifo0_cons_prod_lock"} +// CHECK: %[[FIFO0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "fifo0_cons_cons_lock"} // CHECK: %[[FIFO0_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo0_buff_0"} : memref<1xi32> // CHECK: %[[FIFO0_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo0_buff_1"} : memref<1xi32> -// CHECK: %[[FIFO0_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "fifo0_prod_lock"} -// CHECK: %[[FIFO0_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "fifo0_cons_lock"} +// CHECK: %[[FIFO0_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "fifo0_prod_lock"} +// CHECK: %[[FIFO0_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "fifo0_cons_lock"} // CHECK: %[[BUF83:.*]] = aie.buffer(%[[TILE_8_3]]) {sym_name = "buf83"} : memref<1xi32> // CHECK: aie.flow(%[[TILE_2_2]], DMA : 0, %[[TILE_2_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_8_3]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_delayed_release.mlir b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_delayed_release.mlir index 394fcae06..1f1dbd3c6 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_delayed_release.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_delayed_release.mlir @@ -9,8 +9,8 @@ // CHECK: %[[FIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_1"} : memref // CHECK: %[[FIFO_BUFF_2:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_2"} : memref // CHECK: %[[FIFO_BUFF_3:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_3"} : memref -// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 4 : i32, sym_name = "fifo_prod_lock"} -// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "fifo_cons_lock"} +// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 4 : i8, sym_name = "fifo_prod_lock"} +// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "fifo_cons_lock"} // CHECK: %[[BUF23:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "buf23"} : memref<4xi32> // CHECK: %[[CORE_2_2:.*]] = aie.core(%[[TILE_2_2]]) { // CHECK: %[[C99_I32:.*]] = arith.constant 99 : i32 diff --git a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_static_l1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_static_l1.mlir index 138668aad..cd400e75a 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/AIE2_static_l1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/AIE2_static_l1.mlir @@ -14,8 +14,8 @@ // CHECK: %[[FIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_1"} : memref // CHECK: %[[FIFO_BUFF_2:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_2"} : memref // CHECK: %[[FIFO_BUFF_3:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "fifo_buff_3"} : memref -// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 4 : i32, sym_name = "fifo_prod_lock"} -// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "fifo_cons_lock"} +// CHECK: %[[FIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 4 : i8, sym_name = "fifo_prod_lock"} +// CHECK: %[[FIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "fifo_cons_lock"} // CHECK: %[[DSTBUF22:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "dstbuf22"} : memref<16xi32> // CHECK: %[[CORE_2_2:.*]] = aie.core(%[[TILE_2_2]]) { // CHECK: %[[C0_I32:.*]] = arith.constant 0 : i32 diff --git a/compiler/plugins/target/AMD-AIE/aie/test/aie2_memtile_connection.mlir b/compiler/plugins/target/AMD-AIE/aie/test/aie2_memtile_connection.mlir index b333a88fe..f1e3fb759 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/aie2_memtile_connection.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/aie2_memtile_connection.mlir @@ -5,28 +5,28 @@ //CHECK: %[[T02:.*]] = aie.tile(0, 2) //CHECK: %{{.*}} = aie.switchbox(%[[T02]]) { //CHECK: %0 = aie.amsel<0> (0) -//CHECK: %1 = aie.masterset(South : 1, %0) +//CHECK: %1 = aie.masterset(SOUTH : 1, %0) //CHECK: aie.packet_rules(DMA : 0) { //CHECK: aie.rule(31, 0, %0) //CHECK: } //CHECK: } //CHECK: %{{.*}} = aie.switchbox(%[[T00]]) { -//CHECK: aie.connect +//CHECK: aie.connect //CHECK: %0 = aie.amsel<0> (0) -//CHECK: %1 = aie.masterset(South : 3, %0) -//CHECK: aie.packet_rules(North : 1) { +//CHECK: %1 = aie.masterset(SOUTH : 3, %0) +//CHECK: aie.packet_rules(NORTH : 1) { //CHECK: aie.rule(31, 0, %0) //CHECK: } //CHECK: } //CHECK: %{{.*}} = aie.shim_mux(%[[T00]]) { -//CHECK: aie.connect -//CHECK: aie.connect +//CHECK: aie.connect +//CHECK: aie.connect //CHECK: } //CHECK: %{{.*}} = aie.switchbox(%[[T01]]) { -//CHECK: aie.connect +//CHECK: aie.connect //CHECK: %0 = aie.amsel<0> (0) -//CHECK: %1 = aie.masterset(South : 1, %0) -//CHECK: aie.packet_rules(North : 1) { +//CHECK: %1 = aie.masterset(SOUTH : 1, %0) +//CHECK: aie.packet_rules(NORTH : 1) { //CHECK: aie.rule(31, 0, %0) //CHECK: } //CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/allocation_info_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/allocation_info_test.mlir index f63dc8636..749c550eb 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/allocation_info_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/allocation_info_test.mlir @@ -13,30 +13,30 @@ // CHECK: %[[TILE_2_0:.*]] = aie.tile(2, 0) // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) -// CHECK: %[[OF_OUT_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 6) {init = 0 : i32, sym_name = "of_out_1_cons_prod_lock"} -// CHECK: %[[OF_OUT_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 7) {init = 0 : i32, sym_name = "of_out_1_cons_cons_lock"} +// CHECK: %[[OF_OUT_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 6) {init = 0 : i8, sym_name = "of_out_1_cons_prod_lock"} +// CHECK: %[[OF_OUT_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 7) {init = 0 : i8, sym_name = "of_out_1_cons_cons_lock"} // CHECK: %[[OF_OUT_1_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of_out_1_buff_0"} : memref<64xi16> // CHECK: %[[OF_OUT_1_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of_out_1_buff_1"} : memref<64xi16> -// CHECK: %[[OF_OUT_1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 2) {init = 2 : i32, sym_name = "of_out_1_prod_lock"} -// CHECK: %[[OF_OUT_1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 3) {init = 0 : i32, sym_name = "of_out_1_cons_lock"} +// CHECK: %[[OF_OUT_1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 2) {init = 2 : i8, sym_name = "of_out_1_prod_lock"} +// CHECK: %[[OF_OUT_1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 3) {init = 0 : i8, sym_name = "of_out_1_cons_lock"} // CHECK: %[[OF_IN_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of_in_1_cons_buff_0"} : memref<64xi16> // CHECK: %[[OF_IN_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of_in_1_cons_buff_1"} : memref<64xi16> -// CHECK: %[[OF_IN_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i32, sym_name = "of_in_1_cons_prod_lock"} -// CHECK: %[[OF_IN_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i32, sym_name = "of_in_1_cons_cons_lock"} -// CHECK: %[[OF_IN_1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 4) {init = 0 : i32, sym_name = "of_in_1_prod_lock"} -// CHECK: %[[OF_IN_1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 5) {init = 0 : i32, sym_name = "of_in_1_cons_lock"} -// CHECK: %[[OF_OUT_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 2) {init = 0 : i32, sym_name = "of_out_0_cons_prod_lock"} -// CHECK: %[[OF_OUT_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 3) {init = 0 : i32, sym_name = "of_out_0_cons_cons_lock"} +// CHECK: %[[OF_IN_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i8, sym_name = "of_in_1_cons_prod_lock"} +// CHECK: %[[OF_IN_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i8, sym_name = "of_in_1_cons_cons_lock"} +// CHECK: %[[OF_IN_1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 4) {init = 0 : i8, sym_name = "of_in_1_prod_lock"} +// CHECK: %[[OF_IN_1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 5) {init = 0 : i8, sym_name = "of_in_1_cons_lock"} +// CHECK: %[[OF_OUT_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 2) {init = 0 : i8, sym_name = "of_out_0_cons_prod_lock"} +// CHECK: %[[OF_OUT_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 3) {init = 0 : i8, sym_name = "of_out_0_cons_cons_lock"} // CHECK: %[[OF_OUT_0_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_out_0_buff_0"} : memref<64xi16> // CHECK: %[[OF_OUT_0_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_out_0_buff_1"} : memref<64xi16> -// CHECK: %[[OF_OUT_0_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 2) {init = 2 : i32, sym_name = "of_out_0_prod_lock"} -// CHECK: %[[OF_OUT_0_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 3) {init = 0 : i32, sym_name = "of_out_0_cons_lock"} +// CHECK: %[[OF_OUT_0_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 2) {init = 2 : i8, sym_name = "of_out_0_prod_lock"} +// CHECK: %[[OF_OUT_0_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 3) {init = 0 : i8, sym_name = "of_out_0_cons_lock"} // CHECK: %[[OF_IN_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_in_0_cons_buff_0"} : memref<64xi16> // CHECK: %[[OF_IN_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_in_0_cons_buff_1"} : memref<64xi16> -// CHECK: %[[OF_IN_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of_in_0_cons_prod_lock"} -// CHECK: %[[OF_IN_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of_in_0_cons_cons_lock"} -// CHECK: %[[OF_IN_0_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "of_in_0_prod_lock"} -// CHECK: %[[OF_IN_0_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "of_in_0_cons_lock"} +// CHECK: %[[OF_IN_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of_in_0_cons_prod_lock"} +// CHECK: %[[OF_IN_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of_in_0_cons_cons_lock"} +// CHECK: %[[OF_IN_0_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "of_in_0_prod_lock"} +// CHECK: %[[OF_IN_0_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "of_in_0_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_2]], DMA : 0, %[[TILE_2_0]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_0]], DMA : 1, %[[TILE_2_3]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/bad_npu_nd.mlir b/compiler/plugins/target/AMD-AIE/aie/test/bad_npu_nd.mlir deleted file mode 100644 index 59f3b4cd1..000000000 --- a/compiler/plugins/target/AMD-AIE/aie/test/bad_npu_nd.mlir +++ /dev/null @@ -1,211 +0,0 @@ -// RUN: iree-opt --split-input-file --verify-diagnostics %s - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd_length(%in : memref<1920x1080xi32>, %buf : memref<32xi32>, %out : memref<1920x1080xi32>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c1920 = arith.constant 1920 : i64 - %c1080 = arith.constant 1080 : i64 - // expected-error@+1 {{Size 0 exceeds the [0:1023] range}} - aiex.npu.dma_memcpy_nd (0, 0, %in[%c0,%c0,%c0,%c0][%c1,%c1,%c1080,%c1920][%c0,%c0,%c1920,%c1]) { metadata = @of_fromMem, id = 0 : i64 } : memref<1920x1080xi32> - return - } - aie.shim_dma_allocation @of_fromMem (MM2S, 0, 0) - } -} - -// ----- - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd_repeat(%in : memref<128x4x2x8xi32>, %buf : memref<32xi32>, %out : memref<8192xi32>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c4 = arith.constant 4 : i64 - %c8 = arith.constant 8 : i64 - %c16 = arith.constant 16 : i64 - %c32 = arith.constant 32 : i64 - %c128 = arith.constant 128 : i64 - // expected-error@+1 {{Size 3 exceeds the [1:64] range}} - aiex.npu.dma_memcpy_nd (0, 0, %in[%c0,%c0,%c0,%c0][%c128,%c2,%c2,%c8][%c0,%c16,%c8,%c1]) { metadata = @of_fromMem, id = 0 : i64 } : memref<128x4x2x8xi32> - return - } - aie.shim_dma_allocation @of_fromMem (MM2S, 0, 0) - } -} - -// ----- - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd_stride(%in : memref<8388608xi32>, %buf : memref<32xi32>, %out : memref<8388608xi32>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c2097152 = arith.constant 2097152 : i64 - // expected-error@+1 {{Stride 1 exceeds the [1:1048576] range}} - aiex.npu.dma_memcpy_nd (0, 0, %in[%c0,%c0,%c0,%c0][%c1,%c1,%c2,%c2][%c0,%c0,%c2097152,%c1]) { metadata = @of_fromMem, id = 0 : i64 } : memref<8388608xi32> - return - } - aie.shim_dma_allocation @of_fromMem (MM2S, 0, 0) - } -} - -// ----- - -// Offsets need to be 4-byte aligned. - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd_stride(%a : memref<8xi8>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c8 = arith.constant 8 : i64 - // expected-error@+1 {{Offset must be 4-byte-aligned}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c1][%c1,%c1,%c1,%c8][%c0,%c0,%c1,%c1]) { metadata = @fifo, id = 0 : i64 } : memref<8xi8> - return - } - aie.shim_dma_allocation @fifo (MM2S, 0, 0) - } -} - -// ----- - -// Strides and sizes expressed in types other than i32 should not overflow hardware limitations when converted to 4-byte granularity. -// The following tests check this. - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd(%a : memref<8xi8>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c4 = arith.constant 4 : i64 - %c8 = arith.constant 8 : i64 - %c2048 = arith.constant 2048 : i64 - // Although 2048 exceeds the 0:1023 limit for size 0, since the elements are i8s, - // this should be a size of 512 in address granularity (4 bytes) and hence pass the test. - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c2,%c2048][%c0,%c0,%c4,%c1]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi8> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} - -// ----- - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd(%a : memref<8xi16>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c4 = arith.constant 4 : i64 - %c8 = arith.constant 8 : i64 - %c2048 = arith.constant 2048 : i64 - // expected-error@+1 {{Size 0 exceeds the [0:1023] range}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c2,%c2048][%c0,%c0,%c4,%c1]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi16> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} - -// ----- - -// Strides and sizes are expressed at 4-byte-granularity in hardware, but we express them at memref element type granularity. -// The following tests make sure the proper errors are generated when this is not possible. - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd(%a : memref<8xi8>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 // Stride of 2 i8s = 2 bytes < 4 byte granularity, should not be possible - %c8 = arith.constant 8 : i64 - // expected-error@+1 {{Stride 1 is 2 elements * 1 bytes = 2 bytes, which is not divisible by 4}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c8][%c0,%c0,%c2,%c1]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi8> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} - -// ----- - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd(%a : memref<8xi8>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c4 = arith.constant 4 : i64 - %c8 = arith.constant 8 : i64 - // expected-error@+1 {{2 elements at 1 bytes each equal 2 bytes, which is not divisible by 4}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c2][%c0,%c0,%c4,%c1]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi8> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} - -// ----- - -// stride of 2 i8 is not ok - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd(%a : memref<8xi8>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c2 = arith.constant 2 : i64 - %c4 = arith.constant 4 : i64 - %c8 = arith.constant 8 : i64 - // expected-error@+1 {{Stride 0 is 2 elements * 1 bytes = 2 bytes, which is not divisible by 4}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c8][%c0,%c0,%c0,%c2]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi8> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} - -// ----- - -// stride of 1 i16 is ok, but not with size of 3xi16 - -module { - aie.device(npu1_4col) { - func.func @bad_npu_nd(%a : memref<8xi16>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c3 = arith.constant 3 : i64 - %c8 = arith.constant 8 : i64 - // expected-error@+1 {{3 elements at 2 bytes each equal 6 bytes, which is not divisible by 4}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c3][%c0,%c0,%c0,%c1]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi16> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} - -// ----- - -// bad tile - -module { - aie.device(npu1) { - func.func @bad_npu_nd(%a : memref<8xi16>) { - %c0 = arith.constant 0 : i64 - %c1 = arith.constant 1 : i64 - %c4 = arith.constant 4 : i64 - %c8 = arith.constant 8 : i64 - // expected-error@+1 {{Unsupported tile type at (0, 0) Must be ShimNOC, Mem or Core.}} - aiex.npu.dma_memcpy_nd (0, 0, %a[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c4][%c0,%c0,%c0,%c1]) { metadata = @objectfifo, id = 0 : i64 } : memref<8xi16> - return - } - aie.shim_dma_allocation @objectfifo (MM2S, 0, 0) - } -} diff --git a/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE1.mlir index 57edf239e..0dcd6c415 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE1.mlir @@ -10,18 +10,18 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OF1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "of1_cons_prod_lock"} -// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "of1_cons_cons_lock"} +// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "of1_cons_prod_lock"} +// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "of1_cons_cons_lock"} // CHECK: %[[OF1_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_0"} : memref<16xi32> // CHECK: %[[OF1_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_1"} : memref<16xi32> -// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i32, sym_name = "of1_prod_lock"} -// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i32, sym_name = "of1_cons_lock"} +// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i8, sym_name = "of1_prod_lock"} +// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i8, sym_name = "of1_cons_lock"} // CHECK: %[[OF0_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_0"} : memref<16xi32> // CHECK: %[[OF0_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_1"} : memref<16xi32> // CHECK: %[[OF0_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_2"} : memref<16xi32> // CHECK: %[[OF0_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_3"} : memref<16xi32> -// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "of0_prod_lock"} -// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of0_cons_lock"} +// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "of0_prod_lock"} +// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of0_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: %[[MEM_1_2:.*]] = aie.mem(%[[TILE_1_2]]) { // CHECK: %[[VAL_0:.*]] = aie.dma_start(MM2S, 0, ^bb1, ^bb3) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE2.mlir index db86e19c1..90fee594c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/base_test_AIE2.mlir @@ -10,18 +10,18 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OF1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "of1_cons_prod_lock"} -// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "of1_cons_cons_lock"} +// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "of1_cons_prod_lock"} +// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "of1_cons_cons_lock"} // CHECK: %[[OF1_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_0"} : memref<16xi32> // CHECK: %[[OF1_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_1"} : memref<16xi32> -// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i32, sym_name = "of1_prod_lock"} -// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i32, sym_name = "of1_cons_lock"} +// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i8, sym_name = "of1_prod_lock"} +// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i8, sym_name = "of1_cons_lock"} // CHECK: %[[OF0_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_0"} : memref<16xi32> // CHECK: %[[OF0_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_1"} : memref<16xi32> // CHECK: %[[OF0_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_2"} : memref<16xi32> // CHECK: %[[OF0_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_3"} : memref<16xi32> -// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "of0_prod_lock"} -// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of0_cons_lock"} +// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "of0_prod_lock"} +// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of0_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: %[[MEM_1_2:.*]] = aie.mem(%[[TILE_1_2]]) { // CHECK: %[[VAL_0:.*]] = aie.dma_start(MM2S, 0, ^bb1, ^bb3) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/basic.mlir b/compiler/plugins/target/AMD-AIE/aie/test/basic.mlir index d54043534..e1c7ebf8f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/basic.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/basic.mlir @@ -5,9 +5,9 @@ // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[IN:.*]] = aie.buffer(%[[TILE_2_1]]) {address = 8192 : i32, sym_name = "in"} : memref<16xi32> // CHECK: %[[OUT:.*]] = aie.buffer(%[[TILE_2_1]]) {address = 1824 : i32, sym_name = "out"} : memref<16xi32> -// CHECK: %[[LOCK_2_1:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 1 : i32} +// CHECK: %[[LOCK_2_1:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 1 : i8} // CHECK: %[[LOCK_2_1_0:.*]] = aie.lock(%[[TILE_2_1]], 1) -// CHECK: %[[LOCK_2_1_1:.*]] = aie.lock(%[[TILE_2_1]], 2) {init = 1 : i32} +// CHECK: %[[LOCK_2_1_1:.*]] = aie.lock(%[[TILE_2_1]], 2) {init = 1 : i8} // CHECK: %[[LOCK_2_1_2:.*]] = aie.lock(%[[TILE_2_1]], 3) // CHECK: %[[MEMTILE_DMA_2_1:.*]] = aie.memtile_dma(%[[TILE_2_1]]) { // CHECK: %[[VAL_0:.*]] = aie.dma_start(S2MM, 0, ^bb4, ^bb1) @@ -47,9 +47,9 @@ module @aie_module { %t01 = aie.tile(2, 1) %buf01_0 = aie.buffer(%t01) { address = 8192 : i32, sym_name = "in" } : memref<16xi32> %buf01_1 = aie.buffer(%t01) { address = 1824 : i32, sym_name = "out" } : memref<16xi32> - %l01_0 = aie.lock(%t01, 0) { init = 1 : i32 } + %l01_0 = aie.lock(%t01, 0) { init = 1 : i8 } %l01_1 = aie.lock(%t01, 1) - %l01_2 = aie.lock(%t01, 2) { init = 1 : i32 } + %l01_2 = aie.lock(%t01, 2) { init = 1 : i8 } %l01_3 = aie.lock(%t01, 3) %m01 = aie.memtile_dma(%t01) { %srcDma = aie.dma_start(S2MM, 0, ^bd0, ^dma0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/broadcast_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/broadcast_test.mlir index e5712f29d..a3ddf59ab 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/broadcast_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/broadcast_test.mlir @@ -14,28 +14,28 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[BROADCAST_OF_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "broadcast_of_0_cons_buff_0"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "broadcast_of_0_cons_buff_1"} : memref<16xi32> -// CHECK: %[[BROADCAST_OF_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "broadcast_of_0_cons_prod_lock"} -// CHECK: %[[BROADCAST_OF_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "broadcast_of_0_cons_cons_lock"} +// CHECK: %[[BROADCAST_OF_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "broadcast_of_0_cons_prod_lock"} +// CHECK: %[[BROADCAST_OF_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "broadcast_of_0_cons_cons_lock"} // CHECK: %[[BROADCAST_OF_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_4]]) {sym_name = "broadcast_of_1_cons_buff_0"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_4]]) {sym_name = "broadcast_of_1_cons_buff_1"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_1_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_1_4]]) {sym_name = "broadcast_of_1_cons_buff_2"} : memref<16xi32> -// CHECK: %[[BROADCAST_OF_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_4]], 0) {init = 3 : i32, sym_name = "broadcast_of_1_cons_prod_lock"} -// CHECK: %[[BROADCAST_OF_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_4]], 1) {init = 0 : i32, sym_name = "broadcast_of_1_cons_cons_lock"} +// CHECK: %[[BROADCAST_OF_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_4]], 0) {init = 3 : i8, sym_name = "broadcast_of_1_cons_prod_lock"} +// CHECK: %[[BROADCAST_OF_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_4]], 1) {init = 0 : i8, sym_name = "broadcast_of_1_cons_cons_lock"} // CHECK: %[[BROADCAST_OF_2_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "broadcast_of_2_cons_buff_0"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_2_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "broadcast_of_2_cons_buff_1"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_2_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "broadcast_of_2_cons_buff_2"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_2_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "broadcast_of_2_cons_buff_3"} : memref<16xi32> -// CHECK: %[[BROADCAST_OF_2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 0) {init = 4 : i32, sym_name = "broadcast_of_2_cons_prod_lock"} -// CHECK: %[[BROADCAST_OF_2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 1) {init = 0 : i32, sym_name = "broadcast_of_2_cons_cons_lock"} +// CHECK: %[[BROADCAST_OF_2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 0) {init = 4 : i8, sym_name = "broadcast_of_2_cons_prod_lock"} +// CHECK: %[[BROADCAST_OF_2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 1) {init = 0 : i8, sym_name = "broadcast_of_2_cons_cons_lock"} // CHECK: %[[BROADCAST_OF_3_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "broadcast_of_3_cons_buff_0"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_3_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "broadcast_of_3_cons_buff_1"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_3_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "broadcast_of_3_cons_buff_2"} : memref<16xi32> -// CHECK: %[[BROADCAST_OF_3_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 3 : i32, sym_name = "broadcast_of_3_cons_prod_lock"} -// CHECK: %[[BROADCAST_OF_3_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "broadcast_of_3_cons_cons_lock"} +// CHECK: %[[BROADCAST_OF_3_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 3 : i8, sym_name = "broadcast_of_3_cons_prod_lock"} +// CHECK: %[[BROADCAST_OF_3_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "broadcast_of_3_cons_cons_lock"} // CHECK: %[[BROADCAST_OF_BUFF_0:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "broadcast_of_buff_0"} : memref<16xi32> // CHECK: %[[BROADCAST_OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "broadcast_of_buff_1"} : memref<16xi32> -// CHECK: %[[BROADCAST_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 2 : i32, sym_name = "broadcast_of_prod_lock"} -// CHECK: %[[BROADCAST_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i32, sym_name = "broadcast_of_cons_lock"} +// CHECK: %[[BROADCAST_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 2 : i8, sym_name = "broadcast_of_prod_lock"} +// CHECK: %[[BROADCAST_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i8, sym_name = "broadcast_of_cons_lock"} // CHECK: aie.flow(%[[TILE_1_3]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_3]], DMA : 0, %[[TILE_3_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_3]], DMA : 0, %[[TILE_1_4]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/circuit_and_packet_routing.mlir b/compiler/plugins/target/AMD-AIE/aie/test/circuit_and_packet_routing.mlir index c310762bb..3f329ed6d 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/circuit_and_packet_routing.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/circuit_and_packet_routing.mlir @@ -5,14 +5,14 @@ // CHECK: %[[VAL_1:.*]] = aie.switchbox(%[[VAL_0:.*]]) { // CHECK: %[[VAL_2:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_3:.*]] = aie.masterset(DMA : 1, %[[VAL_2:.*]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 10, %[[VAL_2:.*]]) // CHECK: } // CHECK: } // CHECK: %[[VAL_5:.*]] = aie.tile(7, 3) // CHECK: %[[VAL_6:.*]] = aie.switchbox(%[[VAL_5:.*]]) { // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_8:.*]] = aie.masterset(South : 0, %[[VAL_7:.*]]) +// CHECK: %[[VAL_8:.*]] = aie.masterset(SOUTH : 0, %[[VAL_7:.*]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 10, %[[VAL_7:.*]]) // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/cyclostatic_AIE2_sharedMem.mlir b/compiler/plugins/target/AMD-AIE/aie/test/cyclostatic_AIE2_sharedMem.mlir index 48c48ab95..7b69a46fa 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/cyclostatic_AIE2_sharedMem.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/cyclostatic_AIE2_sharedMem.mlir @@ -9,8 +9,8 @@ // CHECK: %[[FIFO0_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "fifo0_buff_1"} : memref<16xi32> // CHECK: %[[FIFO0_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "fifo0_buff_2"} : memref<16xi32> // CHECK: %[[FIFO0_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "fifo0_buff_3"} : memref<16xi32> -// CHECK: %[[FIFO0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "fifo0_prod_lock"} -// CHECK: %[[FIFO0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "fifo0_cons_lock"} +// CHECK: %[[FIFO0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "fifo0_prod_lock"} +// CHECK: %[[FIFO0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "fifo0_cons_lock"} // CHECK: %[[CORE_1_2:.*]] = aie.core(%[[TILE_1_2]]) { // CHECK: %[[C11_I32:.*]] = arith.constant 11 : i32 // CHECK: %[[C0:.*]] = arith.constant 0 : index diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE1.mlir index 4af29d782..b59acc898 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE1.mlir @@ -11,14 +11,14 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[OF2_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of2_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF2_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of2_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of2_cons_prod_lock"} -// CHECK: %[[OF2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of2_cons_cons_lock"} +// CHECK: %[[OF2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of2_cons_prod_lock"} +// CHECK: %[[OF2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of2_cons_cons_lock"} // CHECK: %[[OF1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "of1_cons_prod_lock"} -// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of1_cons_cons_lock"} -// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "of1_prod_lock"} -// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "of1_cons_lock"} +// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "of1_cons_prod_lock"} +// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of1_cons_cons_lock"} +// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "of1_prod_lock"} +// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "of1_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_1_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: %[[EXT_BUFF_IN:.*]] = aie.external_buffer {sym_name = "ext_buff_in"} : memref<16xi32> diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE2.mlir index 64f88811f..6d2494a7c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_AIE2.mlir @@ -15,12 +15,12 @@ // CHECK: %[[MEM_OUT_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_3]]) {sym_name = "mem_out_cons_buff_1"} : memref<3000xi32> // CHECK: %[[MEM_OUT_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_0_3]]) {sym_name = "mem_out_cons_buff_2"} : memref<3000xi32> // CHECK: %[[MEM_OUT_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_0_3]]) {sym_name = "mem_out_cons_buff_3"} : memref<3000xi32> -// CHECK: %[[MEM_OUT_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_3]], 0) {init = 4 : i32, sym_name = "mem_out_cons_prod_lock"} -// CHECK: %[[MEM_OUT_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_3]], 1) {init = 0 : i32, sym_name = "mem_out_cons_cons_lock"} +// CHECK: %[[MEM_OUT_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_3]], 0) {init = 4 : i8, sym_name = "mem_out_cons_prod_lock"} +// CHECK: %[[MEM_OUT_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_3]], 1) {init = 0 : i8, sym_name = "mem_out_cons_cons_lock"} // CHECK: %[[MEM_IN_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "mem_in_0_cons_buff_0"} : memref<3000xi32> // CHECK: %[[MEM_IN_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "mem_in_0_cons_buff_1"} : memref<3000xi32> -// CHECK: %[[MEM_IN_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 0) {init = 2 : i32, sym_name = "mem_in_0_cons_prod_lock"} -// CHECK: %[[MEM_IN_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 1) {init = 0 : i32, sym_name = "mem_in_0_cons_cons_lock"} +// CHECK: %[[MEM_IN_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 0) {init = 2 : i8, sym_name = "mem_in_0_cons_prod_lock"} +// CHECK: %[[MEM_IN_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 1) {init = 0 : i8, sym_name = "mem_in_0_cons_cons_lock"} // CHECK: %[[MEM_IN_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "mem_in_1_cons_buff_0"} : memref<3000xi32> // CHECK: %[[MEM_IN_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "mem_in_1_cons_buff_1"} : memref<3000xi32> // CHECK: %[[MEM_IN_1_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "mem_in_1_cons_buff_2"} : memref<3000xi32> @@ -28,10 +28,10 @@ // CHECK: %[[MEM_IN_1_CONS_BUFF_4:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "mem_in_1_cons_buff_4"} : memref<3000xi32> // CHECK: %[[MEM_IN_1_CONS_BUFF_5:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "mem_in_1_cons_buff_5"} : memref<3000xi32> // CHECK: %[[MEM_IN_1_CONS_BUFF_6:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "mem_in_1_cons_buff_6"} : memref<3000xi32> -// CHECK: %[[MEM_IN_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 0) {init = 7 : i32, sym_name = "mem_in_1_cons_prod_lock"} -// CHECK: %[[MEM_IN_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 1) {init = 0 : i32, sym_name = "mem_in_1_cons_cons_lock"} -// CHECK: %[[MEM_IN_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 0) {init = 0 : i32, sym_name = "mem_in_prod_lock"} -// CHECK: %[[MEM_IN_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 1) {init = 0 : i32, sym_name = "mem_in_cons_lock"} +// CHECK: %[[MEM_IN_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 0) {init = 7 : i8, sym_name = "mem_in_1_cons_prod_lock"} +// CHECK: %[[MEM_IN_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 1) {init = 0 : i8, sym_name = "mem_in_1_cons_cons_lock"} +// CHECK: %[[MEM_IN_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 0) {init = 0 : i8, sym_name = "mem_in_prod_lock"} +// CHECK: %[[MEM_IN_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 1) {init = 0 : i8, sym_name = "mem_in_cons_lock"} // CHECK: aie.flow(%[[TILE_0_0]], DMA : 0, %[[TILE_0_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_0_0]], DMA : 0, %[[TILE_0_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_0_1]], DMA : 0, %[[TILE_0_3]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_DDR_to_L1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_DDR_to_L1.mlir index f6e2fd751..155227d6d 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_DDR_to_L1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_DDR_to_L1.mlir @@ -11,14 +11,14 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[FROM_MEMTILE_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "from_memTile_cons_buff_0"} : memref<16xi32> // CHECK: %[[FROM_MEMTILE_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "from_memTile_cons_buff_1"} : memref<16xi32> -// CHECK: %[[FROM_MEMTILE_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "from_memTile_cons_prod_lock"} -// CHECK: %[[FROM_MEMTILE_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "from_memTile_cons_cons_lock"} +// CHECK: %[[FROM_MEMTILE_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "from_memTile_cons_prod_lock"} +// CHECK: %[[FROM_MEMTILE_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "from_memTile_cons_cons_lock"} // CHECK: %[[TO_MEMTILE_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "to_memTile_cons_buff_0"} : memref<16xi32> // CHECK: %[[TO_MEMTILE_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "to_memTile_cons_buff_1"} : memref<16xi32> -// CHECK: %[[TO_MEMTILE_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i32, sym_name = "to_memTile_cons_prod_lock"} -// CHECK: %[[TO_MEMTILE_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "to_memTile_cons_cons_lock"} -// CHECK: %[[TO_MEMTILE_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "to_memTile_prod_lock"} -// CHECK: %[[TO_MEMTILE_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "to_memTile_cons_lock"} +// CHECK: %[[TO_MEMTILE_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i8, sym_name = "to_memTile_cons_prod_lock"} +// CHECK: %[[TO_MEMTILE_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "to_memTile_cons_cons_lock"} +// CHECK: %[[TO_MEMTILE_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "to_memTile_prod_lock"} +// CHECK: %[[TO_MEMTILE_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "to_memTile_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: %[[EXT_BUFF_IN:.*]] = aie.external_buffer {sym_name = "ext_buff_in"} : memref<16xi32> diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_L1_to_DDR.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_L1_to_DDR.mlir index dc73db93b..d52d199e1 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_L1_to_DDR.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_L1_to_DDR.mlir @@ -9,16 +9,16 @@ // CHECK: %[[TILE_2_0:.*]] = aie.tile(2, 0) // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) -// CHECK: %[[FROM_MEMTILE_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "from_memTile_cons_prod_lock"} -// CHECK: %[[FROM_MEMTILE_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "from_memTile_cons_cons_lock"} +// CHECK: %[[FROM_MEMTILE_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "from_memTile_cons_prod_lock"} +// CHECK: %[[FROM_MEMTILE_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "from_memTile_cons_cons_lock"} // CHECK: %[[FROM_MEMTILE_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "from_memTile_buff_0"} : memref<48xi32> // CHECK: %[[FROM_MEMTILE_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "from_memTile_buff_1"} : memref<48xi32> -// CHECK: %[[FROM_MEMTILE_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i32, sym_name = "from_memTile_prod_lock"} -// CHECK: %[[FROM_MEMTILE_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "from_memTile_cons_lock"} +// CHECK: %[[FROM_MEMTILE_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i8, sym_name = "from_memTile_prod_lock"} +// CHECK: %[[FROM_MEMTILE_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "from_memTile_cons_lock"} // CHECK: %[[TO_MEMTILE_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "to_memTile_buff_0"} : memref<16xi32> // CHECK: %[[TO_MEMTILE_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "to_memTile_buff_1"} : memref<16xi32> -// CHECK: %[[TO_MEMTILE_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "to_memTile_prod_lock"} -// CHECK: %[[TO_MEMTILE_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "to_memTile_cons_lock"} +// CHECK: %[[TO_MEMTILE_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "to_memTile_prod_lock"} +// CHECK: %[[TO_MEMTILE_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "to_memTile_cons_lock"} // CHECK: aie.flow(%[[TILE_2_2]], DMA : 0, %[[TILE_2_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_2_0]], DMA : 0) // CHECK: %[[EXT_BUFF_IN:.*]] = aie.external_buffer {sym_name = "ext_buff_in"} : memref<48xi32> diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_broadcast.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_broadcast.mlir index 6a01f7e64..b7278a5e5 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_broadcast.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_broadcast.mlir @@ -15,27 +15,27 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[SKIP_CONNECTION_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "skip_connection_cons_buff_0"} : memref<16xi32> // CHECK: %[[SKIP_CONNECTION_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "skip_connection_cons_buff_1"} : memref<16xi32> -// CHECK: %[[SKIP_CONNECTION_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 2) {init = 2 : i32, sym_name = "skip_connection_cons_prod_lock"} -// CHECK: %[[SKIP_CONNECTION_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 3) {init = 0 : i32, sym_name = "skip_connection_cons_cons_lock"} +// CHECK: %[[SKIP_CONNECTION_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 2) {init = 2 : i8, sym_name = "skip_connection_cons_prod_lock"} +// CHECK: %[[SKIP_CONNECTION_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 3) {init = 0 : i8, sym_name = "skip_connection_cons_cons_lock"} // CHECK: %[[SKIP_CONNECTION_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "skip_connection_buff_0"} : memref<16xi32> // CHECK: %[[SKIP_CONNECTION_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "skip_connection_buff_1"} : memref<16xi32> -// CHECK: %[[SKIP_CONNECTION_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 2) {init = 2 : i32, sym_name = "skip_connection_prod_lock"} -// CHECK: %[[SKIP_CONNECTION_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 3) {init = 0 : i32, sym_name = "skip_connection_cons_lock"} +// CHECK: %[[SKIP_CONNECTION_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 2) {init = 2 : i8, sym_name = "skip_connection_prod_lock"} +// CHECK: %[[SKIP_CONNECTION_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 3) {init = 0 : i8, sym_name = "skip_connection_cons_lock"} // CHECK: %[[LINK2_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "link2_0_cons_buff_0"} : memref<16xi32> // CHECK: %[[LINK2_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "link2_0_cons_buff_1"} : memref<16xi32> -// CHECK: %[[LINK2_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "link2_0_cons_prod_lock"} -// CHECK: %[[LINK2_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "link2_0_cons_cons_lock"} +// CHECK: %[[LINK2_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "link2_0_cons_prod_lock"} +// CHECK: %[[LINK2_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "link2_0_cons_cons_lock"} // CHECK: %[[LINK2_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link2_1_cons_buff_0"} : memref<16xi32> // CHECK: %[[LINK2_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link2_1_cons_buff_1"} : memref<16xi32> // CHECK: %[[LINK2_1_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link2_1_cons_buff_2"} : memref<16xi32> -// CHECK: %[[LINK2_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 3 : i32, sym_name = "link2_1_cons_prod_lock"} -// CHECK: %[[LINK2_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "link2_1_cons_cons_lock"} +// CHECK: %[[LINK2_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 3 : i8, sym_name = "link2_1_cons_prod_lock"} +// CHECK: %[[LINK2_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "link2_1_cons_cons_lock"} // CHECK: %[[LINK1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "link1_cons_buff_0"} : memref<48xi32> // CHECK: %[[LINK1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "link1_cons_buff_1"} : memref<48xi32> -// CHECK: %[[LINK1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i32, sym_name = "link1_cons_prod_lock"} -// CHECK: %[[LINK1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "link1_cons_cons_lock"} -// CHECK: %[[LINK1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "link1_prod_lock"} -// CHECK: %[[LINK1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "link1_cons_lock"} +// CHECK: %[[LINK1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i8, sym_name = "link1_cons_prod_lock"} +// CHECK: %[[LINK1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "link1_cons_cons_lock"} +// CHECK: %[[LINK1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "link1_prod_lock"} +// CHECK: %[[LINK1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "link1_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_2_2]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_distribute.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_distribute.mlir index 9dcadcfb2..5ed3b5782 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_distribute.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_distribute.mlir @@ -17,22 +17,22 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[LINK4_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link4_cons_buff_0"} : memref<12xi32> // CHECK: %[[LINK4_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link4_cons_buff_1"} : memref<12xi32> -// CHECK: %[[LINK4_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "link4_cons_prod_lock"} -// CHECK: %[[LINK4_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "link4_cons_cons_lock"} +// CHECK: %[[LINK4_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "link4_cons_prod_lock"} +// CHECK: %[[LINK4_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "link4_cons_cons_lock"} // CHECK: %[[LINK3_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "link3_cons_buff_0"} : memref<20xi32> // CHECK: %[[LINK3_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "link3_cons_buff_1"} : memref<20xi32> -// CHECK: %[[LINK3_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i32, sym_name = "link3_cons_prod_lock"} -// CHECK: %[[LINK3_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i32, sym_name = "link3_cons_cons_lock"} +// CHECK: %[[LINK3_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i8, sym_name = "link3_cons_prod_lock"} +// CHECK: %[[LINK3_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i8, sym_name = "link3_cons_cons_lock"} // CHECK: %[[LINK2_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "link2_cons_buff_0"} : memref<4x4xi32> // CHECK: %[[LINK2_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "link2_cons_buff_1"} : memref<4x4xi32> -// CHECK: %[[LINK2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "link2_cons_prod_lock"} -// CHECK: %[[LINK2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "link2_cons_cons_lock"} +// CHECK: %[[LINK2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "link2_cons_prod_lock"} +// CHECK: %[[LINK2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "link2_cons_cons_lock"} // CHECK: %[[LINK1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "link1_cons_buff_0"} : memref<48xi32> // CHECK: %[[LINK1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "link1_cons_buff_1"} : memref<48xi32> -// CHECK: %[[LINK1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 6 : i32, sym_name = "link1_cons_prod_lock"} -// CHECK: %[[LINK1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "link1_cons_cons_lock"} -// CHECK: %[[LINK1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "link1_prod_lock"} -// CHECK: %[[LINK1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "link1_cons_lock"} +// CHECK: %[[LINK1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 6 : i8, sym_name = "link1_cons_prod_lock"} +// CHECK: %[[LINK1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "link1_cons_cons_lock"} +// CHECK: %[[LINK1_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "link1_prod_lock"} +// CHECK: %[[LINK1_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "link1_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_1]], DMA : 1, %[[TILE_2_3]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/link_test_join.mlir b/compiler/plugins/target/AMD-AIE/aie/test/link_test_join.mlir index f81ffcbfe..367af9e33 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/link_test_join.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/link_test_join.mlir @@ -18,28 +18,28 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) -// CHECK: %[[LINK5_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "link5_cons_prod_lock"} -// CHECK: %[[LINK5_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "link5_cons_cons_lock"} +// CHECK: %[[LINK5_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "link5_cons_prod_lock"} +// CHECK: %[[LINK5_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "link5_cons_cons_lock"} // CHECK: %[[LINK5_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "link5_buff_0"} : memref<512xi8> // CHECK: %[[LINK5_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "link5_buff_1"} : memref<512xi8> -// CHECK: %[[LINK5_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 8 : i32, sym_name = "link5_prod_lock"} -// CHECK: %[[LINK5_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "link5_cons_lock"} +// CHECK: %[[LINK5_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 8 : i8, sym_name = "link5_prod_lock"} +// CHECK: %[[LINK5_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "link5_cons_lock"} // CHECK: %[[LINK4_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link4_buff_0"} : memref<128xi8> // CHECK: %[[LINK4_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "link4_buff_1"} : memref<128xi8> -// CHECK: %[[LINK4_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "link4_prod_lock"} -// CHECK: %[[LINK4_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "link4_cons_lock"} +// CHECK: %[[LINK4_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "link4_prod_lock"} +// CHECK: %[[LINK4_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "link4_cons_lock"} // CHECK: %[[LINK3_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "link3_buff_0"} : memref<128xi8> // CHECK: %[[LINK3_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "link3_buff_1"} : memref<128xi8> -// CHECK: %[[LINK3_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i32, sym_name = "link3_prod_lock"} -// CHECK: %[[LINK3_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i32, sym_name = "link3_cons_lock"} +// CHECK: %[[LINK3_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i8, sym_name = "link3_prod_lock"} +// CHECK: %[[LINK3_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i8, sym_name = "link3_cons_lock"} // CHECK: %[[LINK2_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "link2_buff_0"} : memref<128xi8> // CHECK: %[[LINK2_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "link2_buff_1"} : memref<128xi8> -// CHECK: %[[LINK2_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "link2_prod_lock"} -// CHECK: %[[LINK2_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "link2_cons_lock"} +// CHECK: %[[LINK2_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "link2_prod_lock"} +// CHECK: %[[LINK2_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "link2_cons_lock"} // CHECK: %[[LINK1_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "link1_buff_0"} : memref<128xi8> // CHECK: %[[LINK1_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "link1_buff_1"} : memref<128xi8> -// CHECK: %[[LINK1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "link1_prod_lock"} -// CHECK: %[[LINK1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "link1_cons_lock"} +// CHECK: %[[LINK1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "link1_prod_lock"} +// CHECK: %[[LINK1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "link1_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_2_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_2]], DMA : 0, %[[TILE_2_1]], DMA : 1) // CHECK: aie.flow(%[[TILE_2_3]], DMA : 0, %[[TILE_2_1]], DMA : 2) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/loop_test.aie.mlir b/compiler/plugins/target/AMD-AIE/aie/test/loop_test.aie.mlir index 0a345376c..353951754 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/loop_test.aie.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/loop_test.aie.mlir @@ -9,8 +9,8 @@ // CHECK: %[[LOOP_OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "loop_of_buff_1"} : memref<16xi32> // CHECK: %[[LOOP_OF_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "loop_of_buff_2"} : memref<16xi32> // CHECK: %[[LOOP_OF_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "loop_of_buff_3"} : memref<16xi32> -// CHECK: %[[LOOP_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "loop_of_prod_lock"} -// CHECK: %[[LOOP_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "loop_of_cons_lock"} +// CHECK: %[[LOOP_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "loop_of_prod_lock"} +// CHECK: %[[LOOP_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "loop_of_cons_lock"} // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>, %[[ARG1:.*]]: index) { // CHECK: return // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/loop_test_nested.mlir b/compiler/plugins/target/AMD-AIE/aie/test/loop_test_nested.mlir index 0de536991..96bf70028 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/loop_test_nested.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/loop_test_nested.mlir @@ -7,8 +7,8 @@ // CHECK: %[[TILE_1_3:.*]] = aie.tile(1, 3) // CHECK: %[[LOOP_OF_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "loop_of_buff_0"} : memref<16xi32> // CHECK: %[[LOOP_OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "loop_of_buff_1"} : memref<16xi32> -// CHECK: %[[LOOP_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "loop_of_prod_lock"} -// CHECK: %[[LOOP_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "loop_of_cons_lock"} +// CHECK: %[[LOOP_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "loop_of_prod_lock"} +// CHECK: %[[LOOP_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "loop_of_cons_lock"} // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<4x4xi32>, %[[ARG1:.*]]: index) { // CHECK: return // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/lower_dma.mlir b/compiler/plugins/target/AMD-AIE/aie/test/lower_dma.mlir index 6950cbd20..f661f4feb 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/lower_dma.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/lower_dma.mlir @@ -38,8 +38,8 @@ module @example0 { func.func private @llvm.aie2.put.ms(i32, i32) -> () func.func private @llvm.aie2.mcd.write.vec(vector<16xi32>, i32) -> () - // Odd AIE rows: DMem on the East - // Even AIE rows: DMem on the West + // Odd AIE rows: DMem on the EAST + // Even AIE rows: DMem on the WEST // (2, 4) (3, 4) (4, 4) (5, 4) // (2, 3) (3, 3) (4, 3) (5, 3) @@ -79,11 +79,11 @@ module @example0 { } %s33 = aie.switchbox(%t33) { - aie.connect + aie.connect } %s23 = aie.switchbox(%t23) { - aie.connect + aie.connect } %c33 = aie.core(%t33) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/matmul_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/matmul_test.mlir index 61be787f1..002aad57b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/matmul_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/matmul_test.mlir @@ -10,24 +10,24 @@ // CHECK: memref.global "public" @inA : memref<16x8xi16> // CHECK: %[[TILE_0_0:.*]] = aie.tile(2, 0) // CHECK: %[[TILE_0_2:.*]] = aie.tile(2, 2) -// CHECK: %[[OUTC_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 4) {init = 0 : i32, sym_name = "outC_cons_prod_lock"} -// CHECK: %[[OUTC_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 5) {init = 0 : i32, sym_name = "outC_cons_cons_lock"} +// CHECK: %[[OUTC_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 4) {init = 0 : i8, sym_name = "outC_cons_prod_lock"} +// CHECK: %[[OUTC_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 5) {init = 0 : i8, sym_name = "outC_cons_cons_lock"} // CHECK: %[[OUTC_BUFF_0:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "outC_buff_0"} : memref<16x16xi16> // CHECK: %[[OUTC_BUFF_1:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "outC_buff_1"} : memref<16x16xi16> -// CHECK: %[[OUTC_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 4) {init = 2 : i32, sym_name = "outC_prod_lock"} -// CHECK: %[[OUTC_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 5) {init = 0 : i32, sym_name = "outC_cons_lock"} +// CHECK: %[[OUTC_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 4) {init = 2 : i8, sym_name = "outC_prod_lock"} +// CHECK: %[[OUTC_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 5) {init = 0 : i8, sym_name = "outC_cons_lock"} // CHECK: %[[INB_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "inB_cons_buff_0"} : memref<8x16xi16> // CHECK: %[[INB_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "inB_cons_buff_1"} : memref<8x16xi16> -// CHECK: %[[INB_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 2) {init = 2 : i32, sym_name = "inB_cons_prod_lock"} -// CHECK: %[[INB_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 3) {init = 0 : i32, sym_name = "inB_cons_cons_lock"} -// CHECK: %[[INB_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 2) {init = 0 : i32, sym_name = "inB_prod_lock"} -// CHECK: %[[INB_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 3) {init = 0 : i32, sym_name = "inB_cons_lock"} +// CHECK: %[[INB_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 2) {init = 2 : i8, sym_name = "inB_cons_prod_lock"} +// CHECK: %[[INB_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 3) {init = 0 : i8, sym_name = "inB_cons_cons_lock"} +// CHECK: %[[INB_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 2) {init = 0 : i8, sym_name = "inB_prod_lock"} +// CHECK: %[[INB_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 3) {init = 0 : i8, sym_name = "inB_cons_lock"} // CHECK: %[[INA_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "inA_cons_buff_0"} : memref<16x8xi16> // CHECK: %[[INA_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "inA_cons_buff_1"} : memref<16x8xi16> -// CHECK: %[[INA_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 0) {init = 2 : i32, sym_name = "inA_cons_prod_lock"} -// CHECK: %[[INA_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 1) {init = 0 : i32, sym_name = "inA_cons_cons_lock"} -// CHECK: %[[INA_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 0) {init = 0 : i32, sym_name = "inA_prod_lock"} -// CHECK: %[[INA_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 1) {init = 0 : i32, sym_name = "inA_cons_lock"} +// CHECK: %[[INA_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 0) {init = 2 : i8, sym_name = "inA_cons_prod_lock"} +// CHECK: %[[INA_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 1) {init = 0 : i8, sym_name = "inA_cons_cons_lock"} +// CHECK: %[[INA_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 0) {init = 0 : i8, sym_name = "inA_prod_lock"} +// CHECK: %[[INA_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_0]], 1) {init = 0 : i8, sym_name = "inA_cons_lock"} // CHECK: aie.flow(%[[TILE_0_0]], DMA : 0, %[[TILE_0_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_0_0]], DMA : 1, %[[TILE_0_2]], DMA : 1) // CHECK: aie.flow(%[[TILE_0_2]], DMA : 0, %[[TILE_0_0]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/memTile_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/memTile_test.mlir index c97a59633..26a8a9936 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/memTile_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/memTile_test.mlir @@ -8,12 +8,12 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[OF_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of_cons_prod_lock"} -// CHECK: %[[OF_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of_cons_cons_lock"} +// CHECK: %[[OF_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of_cons_prod_lock"} +// CHECK: %[[OF_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of_cons_cons_lock"} // CHECK: %[[OF_BUFF_0:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "of_buff_0"} : memref<16xi32> // CHECK: %[[OF_BUFF_1:.*]] = aie.buffer(%[[TILE_2_1]]) {sym_name = "of_buff_1"} : memref<16xi32> -// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i32, sym_name = "of_prod_lock"} -// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i32, sym_name = "of_cons_lock"} +// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 2 : i8, sym_name = "of_prod_lock"} +// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_1]], 1) {init = 0 : i8, sym_name = "of_cons_lock"} // CHECK: aie.flow(%[[TILE_2_1]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: %[[MEMTILE_DMA_2_1:.*]] = aie.memtile_dma(%[[TILE_2_1]]) { // CHECK: %[[VAL_0:.*]] = aie.dma_start(MM2S, 0, ^bb1, ^bb3) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_base_AIE2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_base_AIE2.mlir index 612b452de..5950e912e 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_base_AIE2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_base_AIE2.mlir @@ -11,24 +11,24 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OF1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_1"} : memref<256xi32> -// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "of1_cons_prod_lock"} -// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "of1_cons_cons_lock"} +// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "of1_cons_prod_lock"} +// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "of1_cons_cons_lock"} // CHECK: %[[OF1_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_0"} : memref<256xi32> // CHECK: %[[OF1_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_1"} : memref<256xi32> -// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i32, sym_name = "of1_prod_lock"} -// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i32, sym_name = "of1_cons_lock"} +// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i8, sym_name = "of1_prod_lock"} +// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i8, sym_name = "of1_cons_lock"} // CHECK: %[[OF0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_cons_buff_1"} : memref<256xi32> // CHECK: %[[OF0_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_cons_buff_2"} : memref<256xi32> // CHECK: %[[OF0_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_cons_buff_3"} : memref<256xi32> -// CHECK: %[[OF0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 4 : i32, sym_name = "of0_cons_prod_lock"} -// CHECK: %[[OF0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i32, sym_name = "of0_cons_cons_lock"} +// CHECK: %[[OF0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 4 : i8, sym_name = "of0_cons_prod_lock"} +// CHECK: %[[OF0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i8, sym_name = "of0_cons_cons_lock"} // CHECK: %[[OF0_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_0"} : memref<256xi32> // CHECK: %[[OF0_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_1"} : memref<256xi32> // CHECK: %[[OF0_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_2"} : memref<256xi32> // CHECK: %[[OF0_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_3"} : memref<256xi32> -// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "of0_prod_lock"} -// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of0_cons_lock"} +// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "of0_prod_lock"} +// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of0_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_1_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_2]], DMA : 1, %[[TILE_3_3]], DMA : 0) // CHECK: %[[MEM_1_2:.*]] = aie.mem(%[[TILE_1_2]]) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_distribute_AIE2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_distribute_AIE2.mlir index cf94a66b9..2127fac4a 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_distribute_AIE2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_distribute_AIE2.mlir @@ -14,18 +14,18 @@ // CHECK: %[[TILE_2_3:.*]] = aie.tile(3, 3) // CHECK: %[[OF2_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of2_cons_buff_0"} : memref<128xi32> // CHECK: %[[OF2_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of2_cons_buff_1"} : memref<128xi32> -// CHECK: %[[OF2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i32, sym_name = "of2_cons_prod_lock"} -// CHECK: %[[OF2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i32, sym_name = "of2_cons_cons_lock"} +// CHECK: %[[OF2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i8, sym_name = "of2_cons_prod_lock"} +// CHECK: %[[OF2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i8, sym_name = "of2_cons_cons_lock"} // CHECK: %[[OF1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of1_cons_buff_0"} : memref<128xi32> // CHECK: %[[OF1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of1_cons_buff_1"} : memref<128xi32> -// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of1_cons_prod_lock"} -// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of1_cons_cons_lock"} +// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of1_cons_prod_lock"} +// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of1_cons_cons_lock"} // CHECK: %[[OF0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_1]]) {sym_name = "of0_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_1]]) {sym_name = "of0_cons_buff_1"} : memref<256xi32> -// CHECK: %[[OF0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_1]], 0) {init = 4 : i32, sym_name = "of0_cons_prod_lock"} -// CHECK: %[[OF0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_1]], 1) {init = 0 : i32, sym_name = "of0_cons_cons_lock"} -// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_0]], 0) {init = 0 : i32, sym_name = "of0_prod_lock"} -// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_0]], 1) {init = 0 : i32, sym_name = "of0_cons_lock"} +// CHECK: %[[OF0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_1]], 0) {init = 4 : i8, sym_name = "of0_cons_prod_lock"} +// CHECK: %[[OF0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_1]], 1) {init = 0 : i8, sym_name = "of0_cons_cons_lock"} +// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_0]], 0) {init = 0 : i8, sym_name = "of0_prod_lock"} +// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_0]], 1) {init = 0 : i8, sym_name = "of0_cons_lock"} // CHECK: aie.flow(%[[TILE_1_0]], DMA : 0, %[[TILE_1_1]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_1]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_1]], DMA : 1, %[[TILE_2_3]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_multiple_consumers_AIE2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_multiple_consumers_AIE2.mlir index d51f75ca2..1aed3daf7 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_multiple_consumers_AIE2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/nd_dma_multiple_consumers_AIE2.mlir @@ -16,38 +16,38 @@ // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[OF3_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of3_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF3_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of3_cons_buff_1"} : memref<256xi32> -// CHECK: %[[OF3_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i32, sym_name = "of3_cons_prod_lock"} -// CHECK: %[[OF3_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i32, sym_name = "of3_cons_cons_lock"} +// CHECK: %[[OF3_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i8, sym_name = "of3_cons_prod_lock"} +// CHECK: %[[OF3_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i8, sym_name = "of3_cons_cons_lock"} // CHECK: %[[OF3_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of3_buff_0"} : memref<256xi32> // CHECK: %[[OF3_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of3_buff_1"} : memref<256xi32> -// CHECK: %[[OF3_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of3_prod_lock"} -// CHECK: %[[OF3_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of3_cons_lock"} +// CHECK: %[[OF3_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of3_prod_lock"} +// CHECK: %[[OF3_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of3_cons_lock"} // CHECK: %[[OF1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of1_cons_buff_1"} : memref<256xi32> -// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 2) {init = 2 : i32, sym_name = "of1_cons_prod_lock"} -// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 3) {init = 0 : i32, sym_name = "of1_cons_cons_lock"} +// CHECK: %[[OF1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 2) {init = 2 : i8, sym_name = "of1_cons_prod_lock"} +// CHECK: %[[OF1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 3) {init = 0 : i8, sym_name = "of1_cons_cons_lock"} // CHECK: %[[OF1_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_0"} : memref<256xi32> // CHECK: %[[OF1_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of1_buff_1"} : memref<256xi32> -// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i32, sym_name = "of1_prod_lock"} -// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i32, sym_name = "of1_cons_lock"} +// CHECK: %[[OF1_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i8, sym_name = "of1_prod_lock"} +// CHECK: %[[OF1_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i8, sym_name = "of1_cons_lock"} // CHECK: %[[OF0_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_0_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF0_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_0_cons_buff_1"} : memref<256xi32> // CHECK: %[[OF0_0_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_0_cons_buff_2"} : memref<256xi32> // CHECK: %[[OF0_0_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of0_0_cons_buff_3"} : memref<256xi32> -// CHECK: %[[OF0_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 4 : i32, sym_name = "of0_0_cons_prod_lock"} -// CHECK: %[[OF0_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i32, sym_name = "of0_0_cons_cons_lock"} +// CHECK: %[[OF0_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 4 : i8, sym_name = "of0_0_cons_prod_lock"} +// CHECK: %[[OF0_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i8, sym_name = "of0_0_cons_cons_lock"} // CHECK: %[[OF0_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of0_1_cons_buff_0"} : memref<256xi32> // CHECK: %[[OF0_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of0_1_cons_buff_1"} : memref<256xi32> // CHECK: %[[OF0_1_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of0_1_cons_buff_2"} : memref<256xi32> // CHECK: %[[OF0_1_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of0_1_cons_buff_3"} : memref<256xi32> -// CHECK: %[[OF0_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 4 : i32, sym_name = "of0_1_cons_prod_lock"} -// CHECK: %[[OF0_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "of0_1_cons_cons_lock"} +// CHECK: %[[OF0_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 4 : i8, sym_name = "of0_1_cons_prod_lock"} +// CHECK: %[[OF0_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "of0_1_cons_cons_lock"} // CHECK: %[[OF0_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_0"} : memref<256xi32> // CHECK: %[[OF0_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_1"} : memref<256xi32> // CHECK: %[[OF0_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_2"} : memref<256xi32> // CHECK: %[[OF0_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of0_buff_3"} : memref<256xi32> -// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "of0_prod_lock"} -// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of0_cons_lock"} +// CHECK: %[[OF0_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "of0_prod_lock"} +// CHECK: %[[OF0_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of0_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_1_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_1_2]], DMA : 1, %[[TILE_3_3]], DMA : 1) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/nested_loop_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/nested_loop_test.mlir index 06c8682f3..2d93ce41d 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/nested_loop_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/nested_loop_test.mlir @@ -16,38 +16,38 @@ // CHECK: %[[IN8_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in8_cons_buff_1"} : memref<32x32xi32, 1> // CHECK: %[[IN8_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in8_cons_buff_2"} : memref<32x32xi32, 1> // CHECK: %[[IN8_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in8_cons_buff_3"} : memref<32x32xi32, 1> -// CHECK: %[[IN8_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 4) {init = 4 : i32, sym_name = "in8_cons_prod_lock"} -// CHECK: %[[IN8_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 5) {init = 0 : i32, sym_name = "in8_cons_cons_lock"} +// CHECK: %[[IN8_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 4) {init = 4 : i8, sym_name = "in8_cons_prod_lock"} +// CHECK: %[[IN8_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 5) {init = 0 : i8, sym_name = "in8_cons_cons_lock"} // CHECK: %[[IN8_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "in8_buff_0"} : memref<32x32xi32, 1> // CHECK: %[[IN8_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "in8_buff_1"} : memref<32x32xi32, 1> -// CHECK: %[[IN8_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 4) {init = 2 : i32, sym_name = "in8_prod_lock"} -// CHECK: %[[IN8_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 5) {init = 0 : i32, sym_name = "in8_cons_lock"} +// CHECK: %[[IN8_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 4) {init = 2 : i8, sym_name = "in8_prod_lock"} +// CHECK: %[[IN8_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 5) {init = 0 : i8, sym_name = "in8_cons_lock"} // CHECK: %[[IN7_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "in7_cons_buff_0"} : memref<64x32xi32, 1> // CHECK: %[[IN7_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "in7_cons_buff_1"} : memref<64x32xi32, 1> -// CHECK: %[[IN7_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i32, sym_name = "in7_cons_prod_lock"} -// CHECK: %[[IN7_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i32, sym_name = "in7_cons_cons_lock"} +// CHECK: %[[IN7_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 2 : i8, sym_name = "in7_cons_prod_lock"} +// CHECK: %[[IN7_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i8, sym_name = "in7_cons_cons_lock"} // CHECK: %[[IN7_BUFF_0:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in7_buff_0"} : memref<64x32xi32, 1> // CHECK: %[[IN7_BUFF_1:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in7_buff_1"} : memref<64x32xi32, 1> // CHECK: %[[IN7_BUFF_2:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in7_buff_2"} : memref<64x32xi32, 1> // CHECK: %[[IN7_BUFF_3:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in7_buff_3"} : memref<64x32xi32, 1> -// CHECK: %[[IN7_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 2) {init = 4 : i32, sym_name = "in7_prod_lock"} -// CHECK: %[[IN7_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 3) {init = 0 : i32, sym_name = "in7_cons_lock"} +// CHECK: %[[IN7_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 2) {init = 4 : i8, sym_name = "in7_prod_lock"} +// CHECK: %[[IN7_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 3) {init = 0 : i8, sym_name = "in7_cons_lock"} // CHECK: %[[IN2_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "in2_0_cons_buff_0"} : memref<32x64xi32, 1> // CHECK: %[[IN2_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "in2_0_cons_buff_1"} : memref<32x64xi32, 1> // CHECK: %[[IN2_0_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "in2_0_cons_buff_2"} : memref<32x64xi32, 1> // CHECK: %[[IN2_0_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_0_2]]) {sym_name = "in2_0_cons_buff_3"} : memref<32x64xi32, 1> -// CHECK: %[[IN2_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 0) {init = 4 : i32, sym_name = "in2_0_cons_prod_lock"} -// CHECK: %[[IN2_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 1) {init = 0 : i32, sym_name = "in2_0_cons_cons_lock"} +// CHECK: %[[IN2_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 0) {init = 4 : i8, sym_name = "in2_0_cons_prod_lock"} +// CHECK: %[[IN2_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_2]], 1) {init = 0 : i8, sym_name = "in2_0_cons_cons_lock"} // CHECK: %[[IN2_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "in2_1_cons_buff_0"} : memref<32x64xi32, 1> // CHECK: %[[IN2_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "in2_1_cons_buff_1"} : memref<32x64xi32, 1> -// CHECK: %[[IN2_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "in2_1_cons_prod_lock"} -// CHECK: %[[IN2_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "in2_1_cons_cons_lock"} +// CHECK: %[[IN2_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "in2_1_cons_prod_lock"} +// CHECK: %[[IN2_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "in2_1_cons_cons_lock"} // CHECK: %[[IN2_BUFF_0:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in2_buff_0"} : memref<32x64xi32, 1> // CHECK: %[[IN2_BUFF_1:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in2_buff_1"} : memref<32x64xi32, 1> // CHECK: %[[IN2_BUFF_2:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in2_buff_2"} : memref<32x64xi32, 1> // CHECK: %[[IN2_BUFF_3:.*]] = aie.buffer(%[[TILE_0_1]]) {sym_name = "in2_buff_3"} : memref<32x64xi32, 1> -// CHECK: %[[IN2_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 0) {init = 4 : i32, sym_name = "in2_prod_lock"} -// CHECK: %[[IN2_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 1) {init = 0 : i32, sym_name = "in2_cons_lock"} +// CHECK: %[[IN2_PROD_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 0) {init = 4 : i8, sym_name = "in2_prod_lock"} +// CHECK: %[[IN2_CONS_LOCK:.*]] = aie.lock(%[[TILE_0_1]], 1) {init = 0 : i8, sym_name = "in2_cons_lock"} // CHECK: aie.flow(%[[TILE_0_1]], DMA : 0, %[[TILE_1_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_0_1]], DMA : 0, %[[TILE_0_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_0_1]], DMA : 1, %[[TILE_1_2]], DMA : 1) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_1.mlir index a308d057f..88b3b5065 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_1.mlir @@ -8,12 +8,12 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OBJFIFO_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_0"} : memref<16xi32> // CHECK: %[[OBJFIFO_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "objfifo_cons_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "objfifo_cons_cons_lock"} +// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "objfifo_cons_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "objfifo_cons_cons_lock"} // CHECK: %[[OBJFIFO_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_0"} : memref<16xi32> // CHECK: %[[OBJFIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_1"} : memref<16xi32> -// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "objfifo_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "objfifo_cons_lock"} +// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "objfifo_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "objfifo_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return diff --git a/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_2.mlir index 0ed6a3f26..620c16cb6 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_2.mlir @@ -10,12 +10,12 @@ // CHECK: %[[OBJFIFO_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_1"} : memref<16xi32> // CHECK: %[[OBJFIFO_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_2"} : memref<16xi32> // CHECK: %[[OBJFIFO_CONS_BUFF_3:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_3"} : memref<16xi32> -// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 4 : i32, sym_name = "objfifo_cons_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "objfifo_cons_cons_lock"} +// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 4 : i8, sym_name = "objfifo_cons_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "objfifo_cons_cons_lock"} // CHECK: %[[OBJFIFO_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_0"} : memref<16xi32> // CHECK: %[[OBJFIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_1"} : memref<16xi32> -// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "objfifo_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "objfifo_cons_lock"} +// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "objfifo_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "objfifo_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return diff --git a/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_AIE2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_AIE2.mlir index 53a47fc9f..c3be314b8 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_AIE2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/non_adjacency_test_AIE2.mlir @@ -8,12 +8,12 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OF_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "of_cons_prod_lock"} -// CHECK: %[[OF_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "of_cons_cons_lock"} +// CHECK: %[[OF_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "of_cons_prod_lock"} +// CHECK: %[[OF_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "of_cons_cons_lock"} // CHECK: %[[OF_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_0"} : memref<16xi32> // CHECK: %[[OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_1"} : memref<16xi32> -// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i32, sym_name = "of_prod_lock"} -// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of_cons_lock"} +// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 2 : i8, sym_name = "of_prod_lock"} +// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of_cons_lock"} // CHECK: aie.flow(%[[TILE_1_2]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return diff --git a/compiler/plugins/target/AMD-AIE/aie/test/packet_routing_keep_pkt_header.mlir b/compiler/plugins/target/AMD-AIE/aie/test/packet_routing_keep_pkt_header.mlir index 7459dba82..f734d40da 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/packet_routing_keep_pkt_header.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/packet_routing_keep_pkt_header.mlir @@ -5,14 +5,14 @@ // CHECK: %[[VAL_1:.*]] = aie.switchbox(%[[VAL_0]]) { // CHECK: %[[VAL_2:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_3:.*]] = aie.masterset(DMA : 1, %[[VAL_2]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 1, %[[VAL_2]]) // CHECK: } // CHECK: } // CHECK: %[[VAL_4:.*]] = aie.tile(6, 3) // CHECK: %[[VAL_5:.*]] = aie.switchbox(%[[VAL_4]]) { // CHECK: %[[VAL_6:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_7:.*]] = aie.masterset(South : 0, %[[VAL_6]]) +// CHECK: %[[VAL_7:.*]] = aie.masterset(SOUTH : 0, %[[VAL_6]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 1, %[[VAL_6]]) // CHECK: } @@ -21,14 +21,14 @@ // CHECK: %[[VAL_9:.*]] = aie.switchbox(%[[VAL_8]]) { // CHECK: %[[VAL_10:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_11:.*]] = aie.masterset(DMA : 1, %[[VAL_10]]) {keep_pkt_header = "true"} -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 2, %[[VAL_10]]) // CHECK: } // CHECK: } // CHECK: %[[VAL_12:.*]] = aie.tile(7, 3) // CHECK: %[[VAL_13:.*]] = aie.switchbox(%[[VAL_12]]) { // CHECK: %[[VAL_14:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_15:.*]] = aie.masterset(South : 0, %[[VAL_14]]) +// CHECK: %[[VAL_15:.*]] = aie.masterset(SOUTH : 0, %[[VAL_14]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 2, %[[VAL_14]]) // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/register_external_buffers_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/register_external_buffers_test.mlir index f94378689..5d320a955 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/register_external_buffers_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/register_external_buffers_test.mlir @@ -9,10 +9,10 @@ // CHECK: %[[EXT_OF_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "ext_of_cons_buff_0"} : memref<16xi32> // CHECK: %[[EXT_OF_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "ext_of_cons_buff_1"} : memref<16xi32> // CHECK: %[[EXT_OF_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "ext_of_cons_buff_2"} : memref<16xi32> -// CHECK: %[[EXT_OF_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 0) {init = 3 : i32, sym_name = "ext_of_cons_prod_lock"} -// CHECK: %[[EXT_OF_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 1) {init = 0 : i32, sym_name = "ext_of_cons_cons_lock"} -// CHECK: %[[EXT_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 0) {init = 0 : i32, sym_name = "ext_of_prod_lock"} -// CHECK: %[[EXT_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 1) {init = 0 : i32, sym_name = "ext_of_cons_lock"} +// CHECK: %[[EXT_OF_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 0) {init = 3 : i8, sym_name = "ext_of_cons_prod_lock"} +// CHECK: %[[EXT_OF_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 1) {init = 0 : i8, sym_name = "ext_of_cons_cons_lock"} +// CHECK: %[[EXT_OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 0) {init = 0 : i8, sym_name = "ext_of_prod_lock"} +// CHECK: %[[EXT_OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 1) {init = 0 : i8, sym_name = "ext_of_cons_lock"} // CHECK: aie.flow(%[[TILE_3_0]], DMA : 0, %[[TILE_3_2]], DMA : 0) // CHECK: %[[EXT_BUFFER_IN:.*]] = aie.external_buffer {sym_name = "ext_buffer_in"} : memref<64xi32> // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>, %[[ARG1:.*]]: memref<16xi32>) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/same_core_producer_consumer_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/same_core_producer_consumer_test.mlir index e8e9e157b..a68be25a4 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/same_core_producer_consumer_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/same_core_producer_consumer_test.mlir @@ -7,8 +7,8 @@ // CHECK: %[[OF_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_0"} : memref<16xi32> // CHECK: %[[OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_1"} : memref<16xi32> // CHECK: %[[OF_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_2"} : memref<16xi32> -// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 3 : i32, sym_name = "of_prod_lock"} -// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of_cons_lock"} +// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 3 : i8, sym_name = "of_prod_lock"} +// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of_cons_lock"} // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/shimRow_mem_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/shimRow_mem_test.mlir index 0f74f8480..57c19533b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/shimRow_mem_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/shimRow_mem_test.mlir @@ -9,10 +9,10 @@ // CHECK: %[[OBJFIFO_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "objfifo_cons_buff_0"} : memref<16xi32> // CHECK: %[[OBJFIFO_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "objfifo_cons_buff_1"} : memref<16xi32> // CHECK: %[[OBJFIFO_CONS_BUFF_2:.*]] = aie.buffer(%[[TILE_3_2]]) {sym_name = "objfifo_cons_buff_2"} : memref<16xi32> -// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 0) {init = 3 : i32, sym_name = "objfifo_cons_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 1) {init = 0 : i32, sym_name = "objfifo_cons_cons_lock"} -// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 0) {init = 0 : i32, sym_name = "objfifo_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 1) {init = 0 : i32, sym_name = "objfifo_cons_lock"} +// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 0) {init = 3 : i8, sym_name = "objfifo_cons_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_2]], 1) {init = 0 : i8, sym_name = "objfifo_cons_cons_lock"} +// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 0) {init = 0 : i8, sym_name = "objfifo_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_0]], 1) {init = 0 : i8, sym_name = "objfifo_cons_lock"} // CHECK: aie.flow(%[[TILE_3_0]], DMA : 0, %[[TILE_3_2]], DMA : 0) // CHECK: %[[EXT_BUFFER_IN:.*]] = aie.external_buffer {sym_name = "ext_buffer_in"} : memref<64xi32> // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>, %[[ARG1:.*]]: memref<16xi32>) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/shim_AIE2_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/shim_AIE2_test.mlir index 72840fd2c..c46d46826 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/shim_AIE2_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/shim_AIE2_test.mlir @@ -8,18 +8,18 @@ // CHECK: memref.global "public" @of_in : memref<16xi32> // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[TILE_2_0:.*]] = aie.tile(2, 0) -// CHECK: %[[OF_OUT_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 2) {init = 0 : i32, sym_name = "of_out_cons_prod_lock"} -// CHECK: %[[OF_OUT_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 3) {init = 0 : i32, sym_name = "of_out_cons_cons_lock"} +// CHECK: %[[OF_OUT_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 2) {init = 0 : i8, sym_name = "of_out_cons_prod_lock"} +// CHECK: %[[OF_OUT_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 3) {init = 0 : i8, sym_name = "of_out_cons_cons_lock"} // CHECK: %[[OF_OUT_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_out_buff_0"} : memref<16xi32> // CHECK: %[[OF_OUT_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_out_buff_1"} : memref<16xi32> -// CHECK: %[[OF_OUT_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 2) {init = 2 : i32, sym_name = "of_out_prod_lock"} -// CHECK: %[[OF_OUT_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 3) {init = 0 : i32, sym_name = "of_out_cons_lock"} +// CHECK: %[[OF_OUT_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 2) {init = 2 : i8, sym_name = "of_out_prod_lock"} +// CHECK: %[[OF_OUT_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 3) {init = 0 : i8, sym_name = "of_out_cons_lock"} // CHECK: %[[OF_IN_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_in_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF_IN_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_in_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF_IN_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of_in_cons_prod_lock"} -// CHECK: %[[OF_IN_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of_in_cons_cons_lock"} -// CHECK: %[[OF_IN_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "of_in_prod_lock"} -// CHECK: %[[OF_IN_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "of_in_cons_lock"} +// CHECK: %[[OF_IN_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of_in_cons_prod_lock"} +// CHECK: %[[OF_IN_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of_in_cons_cons_lock"} +// CHECK: %[[OF_IN_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "of_in_prod_lock"} +// CHECK: %[[OF_IN_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "of_in_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_2]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_2]], DMA : 0, %[[TILE_2_0]], DMA : 0) // CHECK: %[[EXT_BUFFER_IN:.*]] = aie.external_buffer {sym_name = "ext_buffer_in"} : memref<64xi32> diff --git a/compiler/plugins/target/AMD-AIE/aie/test/shim_broadcast_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/shim_broadcast_test.mlir index db50c7895..2738c8655 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/shim_broadcast_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/shim_broadcast_test.mlir @@ -12,18 +12,18 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OF_IN_0_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_in_0_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF_IN_0_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_2]]) {sym_name = "of_in_0_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF_IN_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i32, sym_name = "of_in_0_cons_prod_lock"} -// CHECK: %[[OF_IN_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i32, sym_name = "of_in_0_cons_cons_lock"} +// CHECK: %[[OF_IN_0_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 0) {init = 2 : i8, sym_name = "of_in_0_cons_prod_lock"} +// CHECK: %[[OF_IN_0_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_2]], 1) {init = 0 : i8, sym_name = "of_in_0_cons_cons_lock"} // CHECK: %[[OF_IN_1_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of_in_1_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF_IN_1_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_2_3]]) {sym_name = "of_in_1_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF_IN_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i32, sym_name = "of_in_1_cons_prod_lock"} -// CHECK: %[[OF_IN_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i32, sym_name = "of_in_1_cons_cons_lock"} +// CHECK: %[[OF_IN_1_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 0) {init = 2 : i8, sym_name = "of_in_1_cons_prod_lock"} +// CHECK: %[[OF_IN_1_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_3]], 1) {init = 0 : i8, sym_name = "of_in_1_cons_cons_lock"} // CHECK: %[[OF_IN_2_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of_in_2_cons_buff_0"} : memref<16xi32> // CHECK: %[[OF_IN_2_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "of_in_2_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OF_IN_2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "of_in_2_cons_prod_lock"} -// CHECK: %[[OF_IN_2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "of_in_2_cons_cons_lock"} -// CHECK: %[[OF_IN_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i32, sym_name = "of_in_prod_lock"} -// CHECK: %[[OF_IN_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i32, sym_name = "of_in_cons_lock"} +// CHECK: %[[OF_IN_2_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "of_in_2_cons_prod_lock"} +// CHECK: %[[OF_IN_2_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "of_in_2_cons_cons_lock"} +// CHECK: %[[OF_IN_PROD_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 0) {init = 0 : i8, sym_name = "of_in_prod_lock"} +// CHECK: %[[OF_IN_CONS_LOCK:.*]] = aie.lock(%[[TILE_2_0]], 1) {init = 0 : i8, sym_name = "of_in_cons_lock"} // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_3_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_3]], DMA : 0) // CHECK: aie.flow(%[[TILE_2_0]], DMA : 0, %[[TILE_2_2]], DMA : 0) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/subview_test_1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/subview_test_1.mlir index 7e9c2a9e1..fc3db0d5b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/subview_test_1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/subview_test_1.mlir @@ -9,8 +9,8 @@ // CHECK: %[[OBJFIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_1"} : memref<16xi32> // CHECK: %[[OBJFIFO_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_2"} : memref<16xi32> // CHECK: %[[OBJFIFO_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_3"} : memref<16xi32> -// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "objfifo_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "objfifo_cons_lock"} +// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "objfifo_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "objfifo_cons_lock"} // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/subview_test_2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/subview_test_2.mlir index 14aa671df..8054e3ada 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/subview_test_2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/subview_test_2.mlir @@ -9,14 +9,14 @@ // CHECK: %[[OF2_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of2_buff_0"} : memref<16xi32> // CHECK: %[[OF2_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of2_buff_1"} : memref<16xi32> // CHECK: %[[OF2_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of2_buff_2"} : memref<16xi32> -// CHECK: %[[OF2_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 3 : i32, sym_name = "of2_prod_lock"} -// CHECK: %[[OF2_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i32, sym_name = "of2_cons_lock"} +// CHECK: %[[OF2_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 2) {init = 3 : i8, sym_name = "of2_prod_lock"} +// CHECK: %[[OF2_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 0 : i8, sym_name = "of2_cons_lock"} // CHECK: %[[OF_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_0"} : memref<16xi32> // CHECK: %[[OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_1"} : memref<16xi32> // CHECK: %[[OF_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_2"} : memref<16xi32> // CHECK: %[[OF_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_3"} : memref<16xi32> -// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "of_prod_lock"} -// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of_cons_lock"} +// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "of_prod_lock"} +// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of_cons_lock"} // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/subview_test_3.mlir b/compiler/plugins/target/AMD-AIE/aie/test/subview_test_3.mlir index 878282247..ced67e903 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/subview_test_3.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/subview_test_3.mlir @@ -9,14 +9,14 @@ // CHECK: %[[OF2_BUFF_0:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of2_buff_0"} : memref<16xi32> // CHECK: %[[OF2_BUFF_1:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of2_buff_1"} : memref<16xi32> // CHECK: %[[OF2_BUFF_2:.*]] = aie.buffer(%[[TILE_1_3]]) {sym_name = "of2_buff_2"} : memref<16xi32> -// CHECK: %[[OF2_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 3 : i32, sym_name = "of2_prod_lock"} -// CHECK: %[[OF2_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i32, sym_name = "of2_cons_lock"} +// CHECK: %[[OF2_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 0) {init = 3 : i8, sym_name = "of2_prod_lock"} +// CHECK: %[[OF2_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_3]], 1) {init = 0 : i8, sym_name = "of2_cons_lock"} // CHECK: %[[OF_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_0"} : memref<16xi32> // CHECK: %[[OF_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_1"} : memref<16xi32> // CHECK: %[[OF_BUFF_2:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_2"} : memref<16xi32> // CHECK: %[[OF_BUFF_3:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "of_buff_3"} : memref<16xi32> -// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i32, sym_name = "of_prod_lock"} -// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i32, sym_name = "of_cons_lock"} +// CHECK: %[[OF_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 0) {init = 4 : i8, sym_name = "of_prod_lock"} +// CHECK: %[[OF_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 1) {init = 0 : i8, sym_name = "of_cons_lock"} // CHECK: func.func @some_work(%[[ARG0:.*]]: memref<16xi32>) { // CHECK: return // CHECK: } @@ -55,7 +55,7 @@ // CHECK: } // CHECK: } -module @multiCoreMixedFifo { +module @multiCOREMixedFifo { aie.device(npu1_4col) { %tile12 = aie.tile(1, 2) %tile13 = aie.tile(1, 3) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_congestion0.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_congestion0.mlir index cd426e693..c59e83319 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_congestion0.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_congestion0.mlir @@ -13,7 +13,7 @@ // CHECK: %[[VAL_7:.*]] = aie.masterset(DMA : 2, %[[VAL_3]]) // CHECK: %[[VAL_8:.*]] = aie.masterset(DMA : 3, %[[VAL_4]]) // CHECK: %[[VAL_9:.*]] = aie.masterset(DMA : 4, %[[VAL_1]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 0, %[[VAL_0]]) // CHECK: aie.rule(31, 1, %[[VAL_2]]) // CHECK: aie.rule(31, 2, %[[VAL_3]]) @@ -24,43 +24,43 @@ // CHECK: %[[TILE_0_2:.*]] = aie.tile(0, 2) // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { // CHECK: %[[VAL_10:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_11:.*]] = aie.masterset(South : 0, %[[VAL_10]]) +// CHECK: %[[VAL_11:.*]] = aie.masterset(SOUTH : 0, %[[VAL_10]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 0, %[[VAL_10]]) // CHECK: } // CHECK: aie.packet_rules(DMA : 1) { // CHECK: aie.rule(31, 4, %[[VAL_10]]) // CHECK: } -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(28, 0, %[[VAL_10]]) // CHECK: } // CHECK: } // CHECK: %[[TILE_0_3:.*]] = aie.tile(0, 3) // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { // CHECK: %[[VAL_12:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_13:.*]] = aie.masterset(South : 0, %[[VAL_12]]) +// CHECK: %[[VAL_13:.*]] = aie.masterset(SOUTH : 0, %[[VAL_12]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 1, %[[VAL_12]]) // CHECK: } -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(30, 2, %[[VAL_12]]) // CHECK: } // CHECK: } // CHECK: %[[TILE_0_4:.*]] = aie.tile(0, 4) // CHECK: %[[SWITCHBOX_0_4:.*]] = aie.switchbox(%[[TILE_0_4]]) { // CHECK: %[[VAL_14:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_15:.*]] = aie.masterset(South : 0, %[[VAL_14]]) +// CHECK: %[[VAL_15:.*]] = aie.masterset(SOUTH : 0, %[[VAL_14]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 2, %[[VAL_14]]) // CHECK: } -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 3, %[[VAL_14]]) // CHECK: } // CHECK: } // CHECK: %[[TILE_0_5:.*]] = aie.tile(0, 5) // CHECK: %[[SWITCHBOX_0_5:.*]] = aie.switchbox(%[[TILE_0_5]]) { // CHECK: %[[VAL_16:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_17:.*]] = aie.masterset(South : 0, %[[VAL_16]]) +// CHECK: %[[VAL_17:.*]] = aie.masterset(SOUTH : 0, %[[VAL_16]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 3, %[[VAL_16]]) // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_congestion1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_congestion1.mlir index cd00f755c..b8673460e 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_congestion1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_congestion1.mlir @@ -7,50 +7,50 @@ // CHECK: %[[T04:.*]] = aie.tile(0, 4) // CHECK: %[[T05:.*]] = aie.tile(0, 5) // CHECK: %{{.*}} = aie.switchbox(%[[T01]]) { -// CHECK: aie.connect -// CHECK: aie.connect -// CHECK: aie.connect -// CHECK: aie.connect -// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect // CHECK: %0 = aie.amsel<0> (0) // CHECK: %1 = aie.masterset(DMA : 4, %0) -// CHECK: aie.packet_rules(South : 0) { +// CHECK: aie.packet_rules(SOUTH : 0) { // CHECK: aie.rule(31, 0, %0) // CHECK: } // CHECK: } // CHECK: %{{.*}} = aie.switchbox(%[[T02]]) { -// CHECK: aie.connect -// CHECK: aie.connect -// CHECK: aie.connect -// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect // CHECK: } // CHECK: %{{.*}} = aie.switchbox(%[[T03]]) { -// CHECK: aie.connect -// CHECK: aie.connect -// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect // CHECK: } // CHECK: %{{.*}} = aie.switchbox(%[[T04]]) { -// CHECK: aie.connect -// CHECK: aie.connect +// CHECK: aie.connect +// CHECK: aie.connect // CHECK: } // CHECK: %{{.*}} = aie.switchbox(%[[T05]]) { -// CHECK: aie.connect +// CHECK: aie.connect // CHECK: %0 = aie.amsel<0> (0) -// CHECK: %1 = aie.masterset(East : 0, %0) +// CHECK: %1 = aie.masterset(EAST : 0, %0) // CHECK: aie.packet_rules(DMA : 1) { // CHECK: aie.rule(31, 0, %0) // CHECK: } // CHECK: } // CHECK: %{{.*}} = aie.switchbox(%[[T00]]) { -// CHECK: aie.connect +// CHECK: aie.connect // CHECK: %0 = aie.amsel<0> (0) -// CHECK: %1 = aie.masterset(North : 0, %0) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %1 = aie.masterset(NORTH : 0, %0) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(31, 0, %0) // CHECK: } // CHECK: } // CHECK: %{{.*}} = aie.shim_mux(%[[T00]]) { -// CHECK: aie.connect +// CHECK: aie.connect // CHECK: } module { aie.device(npu1_2col) { diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows0.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows0.mlir index bb95b4136..29a4fc09f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows0.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows0.mlir @@ -9,9 +9,9 @@ module @test_create_packet_flows0 { // The actual indices used for the amsel arguments is unimportant. // CHECK: %[[VAL_6:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (1) -// CHECK: %[[VAL_4:.*]] = aie.masterset(Core : 0, %[[VAL_2:.*]]) -// CHECK: %[[VAL_5:.*]] = aie.masterset(Core : 1, %[[VAL_3:.*]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_4:.*]] = aie.masterset(CORE : 0, %[[VAL_2:.*]]) +// CHECK: %[[VAL_5:.*]] = aie.masterset(CORE : 1, %[[VAL_3:.*]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(31, 0, %[[VAL_2]]) // CHECK-DAG: aie.rule(31, 1, %[[VAL_3]]) // CHECK: } @@ -20,13 +20,13 @@ module @test_create_packet_flows0 { %t11 = aie.tile(1, 1) aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> } aie.packet_flow(0x1) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 1> } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows1.mlir index c21428bcb..33b9f5542 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows1.mlir @@ -4,11 +4,11 @@ // CHECK: %[[TILE_1_1:.*]] = aie.tile(1, 1) // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { // CHECK: %[[VAL_0:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_1:.*]] = aie.masterset(Core : 0, %[[VAL_0]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_1:.*]] = aie.masterset(CORE : 0, %[[VAL_0]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK: aie.rule(31, 0, %[[VAL_0]]) // CHECK: } -// CHECK: aie.packet_rules(West : 1) { +// CHECK: aie.packet_rules(WEST : 1) { // CHECK: aie.rule(31, 1, %[[VAL_0]]) // CHECK: } // CHECK: } @@ -19,13 +19,13 @@ module @test_create_packet_flows1 { %t11 = aie.tile(1, 1) aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> } aie.packet_flow(0x1) { - aie.packet_source<%t11, West : 1> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 1> + aie.packet_dest<%t11, CORE : 0> } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows2.mlir index 0cd50fe61..7029e443c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows2.mlir @@ -5,21 +5,21 @@ // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { // CHECK: %[[VAL_0:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_1:.*]] = aie.amsel<0> (1) -// CHECK: %[[VAL_2:.*]] = aie.masterset(Core : 0, %[[VAL_0]]) -// CHECK: %[[VAL_3:.*]] = aie.masterset(Core : 1, %[[VAL_0]], %[[VAL_1]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_2:.*]] = aie.masterset(CORE : 0, %[[VAL_0]]) +// CHECK: %[[VAL_3:.*]] = aie.masterset(CORE : 1, %[[VAL_0]], %[[VAL_1]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(31, 0, %[[VAL_0]]) // CHECK-DAG: aie.rule(31, 1, %[[VAL_1]]) // CHECK: } // CHECK: } // CHECK: aie.packet_flow(0) { -// CHECK: aie.packet_source<%[[TILE_1_1]], West : 0> -// CHECK: aie.packet_dest<%[[TILE_1_1]], Core : 0> -// CHECK: aie.packet_dest<%[[TILE_1_1]], Core : 1> +// CHECK: aie.packet_source<%[[TILE_1_1]], WEST : 0> +// CHECK: aie.packet_dest<%[[TILE_1_1]], CORE : 0> +// CHECK: aie.packet_dest<%[[TILE_1_1]], CORE : 1> // CHECK: } // CHECK: aie.packet_flow(1) { -// CHECK: aie.packet_source<%[[TILE_1_1]], West : 0> -// CHECK: aie.packet_dest<%[[TILE_1_1]], Core : 1> +// CHECK: aie.packet_source<%[[TILE_1_1]], WEST : 0> +// CHECK: aie.packet_dest<%[[TILE_1_1]], CORE : 1> // CHECK: } // CHECK: } @@ -28,14 +28,14 @@ module @test_create_packet_flows2 { %t11 = aie.tile(1, 1) aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> + aie.packet_dest<%t11, CORE : 1> } aie.packet_flow(0x1) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 1> } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows3.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows3.mlir index b06dc03a1..77deb30fa 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows3.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows3.mlir @@ -5,23 +5,23 @@ // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { // CHECK: %[[VAL_0:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_1:.*]] = aie.amsel<0> (1) -// CHECK: %[[VAL_2:.*]] = aie.masterset(Core : 0, %[[VAL_0]]) -// CHECK: %[[VAL_3:.*]] = aie.masterset(Core : 1, %[[VAL_0]], %[[VAL_1]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_2:.*]] = aie.masterset(CORE : 0, %[[VAL_0]]) +// CHECK: %[[VAL_3:.*]] = aie.masterset(CORE : 1, %[[VAL_0]], %[[VAL_1]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK: aie.rule(31, 0, %[[VAL_0]]) // CHECK: } -// CHECK: aie.packet_rules(West : 1) { +// CHECK: aie.packet_rules(WEST : 1) { // CHECK: aie.rule(31, 1, %[[VAL_1]]) // CHECK: } // CHECK: } // CHECK: aie.packet_flow(0) { -// CHECK: aie.packet_source<%[[TILE_1_1]], West : 0> -// CHECK: aie.packet_dest<%[[TILE_1_1]], Core : 0> -// CHECK: aie.packet_dest<%[[TILE_1_1]], Core : 1> +// CHECK: aie.packet_source<%[[TILE_1_1]], WEST : 0> +// CHECK: aie.packet_dest<%[[TILE_1_1]], CORE : 0> +// CHECK: aie.packet_dest<%[[TILE_1_1]], CORE : 1> // CHECK: } // CHECK: aie.packet_flow(1) { -// CHECK: aie.packet_source<%[[TILE_1_1]], West : 1> -// CHECK: aie.packet_dest<%[[TILE_1_1]], Core : 1> +// CHECK: aie.packet_source<%[[TILE_1_1]], WEST : 1> +// CHECK: aie.packet_dest<%[[TILE_1_1]], CORE : 1> // CHECK: } // CHECK: } @@ -30,14 +30,14 @@ module @test_create_packet_flows3 { %t11 = aie.tile(1, 1) aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> + aie.packet_dest<%t11, CORE : 1> } aie.packet_flow(0x1) { - aie.packet_source<%t11, West : 1> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 1> + aie.packet_dest<%t11, CORE : 1> } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows4.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows4.mlir index a63c4f2da..63551a3f3 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows4.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows4.mlir @@ -7,13 +7,13 @@ module @test_create_packet_flows4 { // CHECK: %[[VAL_1:.*]] = aie.switchbox(%[[VAL_0]]) { // CHECK: %[[VAL_6:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (1) -// CHECK: %[[VAL_4:.*]] = aie.masterset(Core : 0, %[[VAL_3:.*]]) -// CHECK: %[[VAL_5:.*]] = aie.masterset(Core : 1, %[[VAL_2:.*]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_4:.*]] = aie.masterset(CORE : 0, %[[VAL_3:.*]]) +// CHECK: %[[VAL_5:.*]] = aie.masterset(CORE : 1, %[[VAL_2:.*]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(31, 0, %[[VAL_3]]) // CHECK-DAG: aie.rule(31, 1, %[[VAL_2]]) // CHECK: } -// CHECK: aie.packet_rules(West : 1) { +// CHECK: aie.packet_rules(WEST : 1) { // CHECK-DAG: aie.rule(31, 0, %[[VAL_2]]) // CHECK: } // CHECK: } @@ -21,18 +21,18 @@ module @test_create_packet_flows4 { %t11 = aie.tile(1, 1) aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> } aie.packet_flow(0x1) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 1> } aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 1> - aie.packet_dest<%t11, Core : 1> + aie.packet_source<%t11, WEST : 1> + aie.packet_dest<%t11, CORE : 1> } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows5.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows5.mlir index 537b8d5a2..28469c7bd 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows5.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows5.mlir @@ -4,11 +4,11 @@ // CHECK: %[[VAL_0:.*]] = aie.tile(1, 1) // CHECK: %[[VAL_1:.*]] = aie.switchbox(%[[VAL_0]]) { // CHECK: %[[VAL_2:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_3:.*]] = aie.masterset(Core : 0, %[[VAL_2]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_3:.*]] = aie.masterset(CORE : 0, %[[VAL_2]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(30, 0, %[[VAL_2]]) // CHECK: } -// CHECK: aie.packet_rules(West : 1) { +// CHECK: aie.packet_rules(WEST : 1) { // CHECK-DAG: aie.rule(31, 2, %[[VAL_2]]) // CHECK: } // CHECK: } @@ -20,18 +20,18 @@ module @test_create_packet_flows5 { %t11 = aie.tile(1, 1) aie.packet_flow(0x0) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> } aie.packet_flow(0x1) { - aie.packet_source<%t11, West : 0> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 0> + aie.packet_dest<%t11, CORE : 0> } aie.packet_flow(0x2) { - aie.packet_source<%t11, West : 1> - aie.packet_dest<%t11, Core : 0> + aie.packet_source<%t11, WEST : 1> + aie.packet_dest<%t11, CORE : 0> } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows6.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows6.mlir index 132bc20fa..fdeb821c3 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows6.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows6.mlir @@ -4,7 +4,7 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { // CHECK: %[[VAL_0:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_1:.*]] = aie.masterset(East : 0, %[[VAL_0]]) +// CHECK: %[[VAL_1:.*]] = aie.masterset(EAST : 0, %[[VAL_0]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(28, 0, %[[VAL_0]]) // CHECK: } @@ -14,8 +14,8 @@ // CHECK: %[[VAL_2:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_3:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_4:.*]] = aie.masterset(DMA : 0, %[[VAL_2]]) -// CHECK: %[[VAL_5:.*]] = aie.masterset(East : 0, %[[VAL_3]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_5:.*]] = aie.masterset(EAST : 0, %[[VAL_3]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(31, 0, %[[VAL_2]]) // CHECK-DAG: aie.rule(28, 0, %[[VAL_3]]) // CHECK: } @@ -25,8 +25,8 @@ // CHECK: %[[VAL_6:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_8:.*]] = aie.masterset(DMA : 0, %[[VAL_6]]) -// CHECK: %[[VAL_9:.*]] = aie.masterset(East : 0, %[[VAL_7]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_9:.*]] = aie.masterset(EAST : 0, %[[VAL_7]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(30, 2, %[[VAL_7]]) // CHECK-DAG: aie.rule(31, 1, %[[VAL_6]]) // CHECK: } @@ -36,8 +36,8 @@ // CHECK: %[[VAL_10:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_11:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_12:.*]] = aie.masterset(DMA : 0, %[[VAL_10]]) -// CHECK: %[[VAL_13:.*]] = aie.masterset(East : 0, %[[VAL_11]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: %[[VAL_13:.*]] = aie.masterset(EAST : 0, %[[VAL_11]]) +// CHECK: aie.packet_rules(WEST : 0) { // CHECK-DAG: aie.rule(31, 2, %[[VAL_10]]) // CHECK-DAG: aie.rule(31, 3, %[[VAL_11]]) // CHECK: } @@ -46,7 +46,7 @@ // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { // CHECK: %[[VAL_14:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_15:.*]] = aie.masterset(DMA : 0, %[[VAL_14]]) -// CHECK: aie.packet_rules(West : 0) { +// CHECK: aie.packet_rules(WEST : 0) { // CHECK: aie.rule(31, 3, %[[VAL_14]]) // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim0.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim0.mlir index 2026ef2c3..30d0e7e91 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim0.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim0.mlir @@ -3,19 +3,19 @@ // CHECK-LABEL: module @aie_module { // CHECK: %[[VAL_0:.*]] = aie.tile(7, 0) // CHECK: %[[VAL_1:.*]] = aie.shim_mux(%[[VAL_0:.*]]) { -// CHECK: aie.connect +// CHECK: aie.connect // CHECK: } // CHECK: %[[VAL_2:.*]] = aie.switchbox(%[[VAL_0:.*]]) { // CHECK: %[[VAL_3:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_4:.*]] = aie.masterset(South : 3, %[[VAL_3:.*]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: %[[VAL_4:.*]] = aie.masterset(SOUTH : 3, %[[VAL_3:.*]]) +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 10, %[[VAL_3:.*]]) // CHECK: } // CHECK: } // CHECK: %[[VAL_5:.*]] = aie.tile(7, 1) // CHECK: %[[VAL_6:.*]] = aie.switchbox(%[[VAL_5:.*]]) { // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_8:.*]] = aie.masterset(South : 0, %[[VAL_6:.*]]) +// CHECK: %[[VAL_8:.*]] = aie.masterset(SOUTH : 0, %[[VAL_6:.*]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(31, 10, %[[VAL_7:.*]]) // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim1.mlir index 2170c2b42..93b643fa4 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_create_packet_flows_shim1.mlir @@ -3,12 +3,12 @@ // CHECK-LABEL: module @aie_module { // CHECK: %[[VAL_0:.*]] = aie.tile(7, 0) // CHECK: %[[VAL_1:.*]] = aie.shim_mux(%[[VAL_0:.*]]) { -// CHECK: aie.connect +// CHECK: aie.connect // CHECK: } // CHECK: %[[VAL_2:.*]] = aie.switchbox(%[[VAL_0:.*]]) { // CHECK: %[[VAL_3:.*]] = aie.amsel<0> (0) -// CHECK: %[[VAL_4:.*]] = aie.masterset(North : 0, %[[VAL_3:.*]]) -// CHECK: aie.packet_rules(South : 3) { +// CHECK: %[[VAL_4:.*]] = aie.masterset(NORTH : 0, %[[VAL_3:.*]]) +// CHECK: aie.packet_rules(SOUTH : 3) { // CHECK: aie.rule(31, 3, %[[VAL_3:.*]]) // CHECK: } // CHECK: } @@ -16,7 +16,7 @@ // CHECK: %[[VAL_6:.*]] = aie.switchbox(%[[VAL_5:.*]]) { // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_8:.*]] = aie.masterset(DMA : 0, %[[VAL_7:.*]]) -// CHECK: aie.packet_rules(South : 0) { +// CHECK: aie.packet_rules(SOUTH : 0) { // CHECK: aie.rule(31, 3, %[[VAL_7:.*]]) // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/test_pktflow_weight_pusher.mlir b/compiler/plugins/target/AMD-AIE/aie/test/test_pktflow_weight_pusher.mlir index d321178c1..ababa7692 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/test_pktflow_weight_pusher.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/test_pktflow_weight_pusher.mlir @@ -5,7 +5,7 @@ // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { // CHECK: %[[VAL_0:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_1:.*]] = aie.masterset(DMA : 1, %[[VAL_0]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(31, 0, %[[VAL_0]]) // CHECK: } // CHECK: } @@ -14,8 +14,8 @@ // CHECK: %[[VAL_2:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_3:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_4:.*]] = aie.masterset(DMA : 1, %[[VAL_3]]) -// CHECK: %[[VAL_5:.*]] = aie.masterset(West : 0, %[[VAL_2]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %[[VAL_5:.*]] = aie.masterset(WEST : 0, %[[VAL_2]]) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(31, 0, %[[VAL_2]]) // CHECK: aie.rule(31, 4, %[[VAL_3]]) // CHECK: } @@ -25,8 +25,8 @@ // CHECK: %[[VAL_6:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_7:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_8:.*]] = aie.masterset(DMA : 1, %[[VAL_7]]) -// CHECK: %[[VAL_9:.*]] = aie.masterset(West : 0, %[[VAL_6]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: %[[VAL_9:.*]] = aie.masterset(WEST : 0, %[[VAL_6]]) +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(27, 0, %[[VAL_6]]) // CHECK: aie.rule(31, 8, %[[VAL_7]]) // CHECK: } @@ -35,7 +35,7 @@ // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { // CHECK: %[[VAL_10:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_11:.*]] = aie.masterset(DMA : 1, %[[VAL_10]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 12, %[[VAL_10]]) // CHECK: } // CHECK: } @@ -43,7 +43,7 @@ // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { // CHECK: %[[VAL_12:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_13:.*]] = aie.masterset(DMA : 1, %[[VAL_12]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 1, %[[VAL_12]]) // CHECK: } // CHECK: } @@ -51,7 +51,7 @@ // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { // CHECK: %[[VAL_14:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_15:.*]] = aie.masterset(DMA : 1, %[[VAL_14]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(31, 5, %[[VAL_14]]) // CHECK: } // CHECK: } @@ -61,13 +61,13 @@ // CHECK: %[[VAL_17:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_18:.*]] = aie.amsel<0> (2) // CHECK: %[[VAL_19:.*]] = aie.masterset(DMA : 1, %[[VAL_18]]) -// CHECK: %[[VAL_20:.*]] = aie.masterset(South : 0, %[[VAL_16]]) -// CHECK: %[[VAL_21:.*]] = aie.masterset(West : 0, %[[VAL_17]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: %[[VAL_20:.*]] = aie.masterset(SOUTH : 0, %[[VAL_16]]) +// CHECK: %[[VAL_21:.*]] = aie.masterset(WEST : 0, %[[VAL_17]]) +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(27, 0, %[[VAL_16]]) // CHECK: aie.rule(31, 5, %[[VAL_17]]) // CHECK: } -// CHECK: aie.packet_rules(East : 0) { +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(31, 8, %[[VAL_16]]) // CHECK: aie.rule(31, 9, %[[VAL_18]]) // CHECK: } @@ -78,9 +78,9 @@ // CHECK: %[[VAL_23:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_24:.*]] = aie.amsel<0> (2) // CHECK: %[[VAL_25:.*]] = aie.masterset(DMA : 1, %[[VAL_24]]) -// CHECK: %[[VAL_26:.*]] = aie.masterset(South : 0, %[[VAL_23]]) -// CHECK: %[[VAL_27:.*]] = aie.masterset(West : 0, %[[VAL_22]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: %[[VAL_26:.*]] = aie.masterset(SOUTH : 0, %[[VAL_23]]) +// CHECK: %[[VAL_27:.*]] = aie.masterset(WEST : 0, %[[VAL_22]]) +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(30, 8, %[[VAL_22]]) // CHECK: aie.rule(31, 12, %[[VAL_23]]) // CHECK: aie.rule(31, 13, %[[VAL_24]]) @@ -91,8 +91,8 @@ // CHECK: %[[VAL_28:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_29:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_30:.*]] = aie.masterset(DMA : 1, %[[VAL_29]]) -// CHECK: %[[VAL_31:.*]] = aie.masterset(South : 0, %[[VAL_28]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: %[[VAL_31:.*]] = aie.masterset(SOUTH : 0, %[[VAL_28]]) +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 1, %[[VAL_28]]) // CHECK: aie.rule(31, 2, %[[VAL_29]]) // CHECK: } @@ -101,7 +101,7 @@ // CHECK: %[[SWITCHBOX_3_4:.*]] = aie.switchbox(%[[TILE_3_4]]) { // CHECK: %[[VAL_32:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_33:.*]] = aie.masterset(DMA : 1, %[[VAL_32]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(31, 6, %[[VAL_32]]) // CHECK: } // CHECK: } @@ -111,12 +111,12 @@ // CHECK: %[[VAL_35:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_36:.*]] = aie.amsel<0> (2) // CHECK: %[[VAL_37:.*]] = aie.masterset(DMA : 1, %[[VAL_34]]) -// CHECK: %[[VAL_38:.*]] = aie.masterset(South : 0, %[[VAL_35]]) -// CHECK: %[[VAL_39:.*]] = aie.masterset(West : 0, %[[VAL_36]]) -// CHECK: aie.packet_rules(North : 0) { +// CHECK: %[[VAL_38:.*]] = aie.masterset(SOUTH : 0, %[[VAL_35]]) +// CHECK: %[[VAL_39:.*]] = aie.masterset(WEST : 0, %[[VAL_36]]) +// CHECK: aie.packet_rules(NORTH : 0) { // CHECK: aie.rule(31, 10, %[[VAL_34]]) // CHECK: } -// CHECK: aie.packet_rules(East : 0) { +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(26, 0, %[[VAL_35]]) // CHECK: aie.rule(31, 6, %[[VAL_36]]) // CHECK: } @@ -127,9 +127,9 @@ // CHECK: %[[VAL_41:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_42:.*]] = aie.amsel<0> (2) // CHECK: %[[VAL_43:.*]] = aie.masterset(DMA : 1, %[[VAL_42]]) -// CHECK: %[[VAL_44:.*]] = aie.masterset(South : 0, %[[VAL_41]]) -// CHECK: %[[VAL_45:.*]] = aie.masterset(West : 0, %[[VAL_40]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %[[VAL_44:.*]] = aie.masterset(SOUTH : 0, %[[VAL_41]]) +// CHECK: %[[VAL_45:.*]] = aie.masterset(WEST : 0, %[[VAL_40]]) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(24, 0, %[[VAL_40]]) // CHECK: aie.rule(26, 8, %[[VAL_41]]) // CHECK: aie.rule(31, 14, %[[VAL_42]]) @@ -140,8 +140,8 @@ // CHECK: %[[VAL_46:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_47:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_48:.*]] = aie.masterset(DMA : 1, %[[VAL_47]]) -// CHECK: %[[VAL_49:.*]] = aie.masterset(South : 0, %[[VAL_46]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %[[VAL_49:.*]] = aie.masterset(SOUTH : 0, %[[VAL_46]]) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(28, 0, %[[VAL_46]]) // CHECK: aie.rule(31, 3, %[[VAL_47]]) // CHECK: } @@ -151,8 +151,8 @@ // CHECK: %[[VAL_50:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_51:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_52:.*]] = aie.masterset(DMA : 1, %[[VAL_51]]) -// CHECK: %[[VAL_53:.*]] = aie.masterset(West : 0, %[[VAL_50]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %[[VAL_53:.*]] = aie.masterset(WEST : 0, %[[VAL_50]]) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(28, 0, %[[VAL_50]]) // CHECK: aie.rule(31, 7, %[[VAL_51]]) // CHECK: } @@ -163,9 +163,9 @@ // CHECK: %[[VAL_55:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_56:.*]] = aie.amsel<0> (2) // CHECK: %[[VAL_57:.*]] = aie.masterset(DMA : 1, %[[VAL_56]]) -// CHECK: %[[VAL_58:.*]] = aie.masterset(South : 0, %[[VAL_55]]) -// CHECK: %[[VAL_59:.*]] = aie.masterset(West : 0, %[[VAL_54]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %[[VAL_58:.*]] = aie.masterset(SOUTH : 0, %[[VAL_55]]) +// CHECK: %[[VAL_59:.*]] = aie.masterset(WEST : 0, %[[VAL_54]]) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(24, 0, %[[VAL_54]]) // CHECK: aie.rule(31, 10, %[[VAL_55]]) // CHECK: aie.rule(31, 11, %[[VAL_56]]) @@ -176,8 +176,8 @@ // CHECK: %[[VAL_60:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_61:.*]] = aie.amsel<0> (1) // CHECK: %[[VAL_62:.*]] = aie.masterset(DMA : 1, %[[VAL_61]]) -// CHECK: %[[VAL_63:.*]] = aie.masterset(West : 0, %[[VAL_60]]) -// CHECK: aie.packet_rules(East : 0) { +// CHECK: %[[VAL_63:.*]] = aie.masterset(WEST : 0, %[[VAL_60]]) +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(16, 0, %[[VAL_60]]) // CHECK: aie.rule(31, 15, %[[VAL_61]]) // CHECK: } @@ -186,13 +186,13 @@ // CHECK: %[[SWITCHBOX_6_5:.*]] = aie.switchbox(%[[TILE_6_5]]) { // CHECK: %[[VAL_64:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_65:.*]] = aie.amsel<0> (1) -// CHECK: %[[VAL_66:.*]] = aie.masterset(South : 0, %[[VAL_64]]) -// CHECK: %[[VAL_67:.*]] = aie.masterset(West : 0, %[[VAL_65]]) +// CHECK: %[[VAL_66:.*]] = aie.masterset(SOUTH : 0, %[[VAL_64]]) +// CHECK: %[[VAL_67:.*]] = aie.masterset(WEST : 0, %[[VAL_65]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(24, 0, %[[VAL_64]]) // CHECK: aie.rule(24, 0, %[[VAL_65]]) // CHECK: } -// CHECK: aie.packet_rules(East : 0) { +// CHECK: aie.packet_rules(EAST : 0) { // CHECK: aie.rule(26, 10, %[[VAL_65]]) // CHECK: } // CHECK: } @@ -200,8 +200,8 @@ // CHECK: %[[SWITCHBOX_7_5:.*]] = aie.switchbox(%[[TILE_7_5]]) { // CHECK: %[[VAL_68:.*]] = aie.amsel<0> (0) // CHECK: %[[VAL_69:.*]] = aie.amsel<0> (1) -// CHECK: %[[VAL_70:.*]] = aie.masterset(South : 0, %[[VAL_68]]) -// CHECK: %[[VAL_71:.*]] = aie.masterset(West : 0, %[[VAL_69]]) +// CHECK: %[[VAL_70:.*]] = aie.masterset(SOUTH : 0, %[[VAL_68]]) +// CHECK: %[[VAL_71:.*]] = aie.masterset(WEST : 0, %[[VAL_69]]) // CHECK: aie.packet_rules(DMA : 0) { // CHECK: aie.rule(24, 8, %[[VAL_68]]) // CHECK: aie.rule(26, 10, %[[VAL_69]]) diff --git a/compiler/plugins/target/AMD-AIE/aie/test/tileDMA_test.mlir b/compiler/plugins/target/AMD-AIE/aie/test/tileDMA_test.mlir index e6913470d..6059972da 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/tileDMA_test.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/tileDMA_test.mlir @@ -8,12 +8,12 @@ // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[OBJFIFO_CONS_BUFF_0:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_0"} : memref<16xi32> // CHECK: %[[OBJFIFO_CONS_BUFF_1:.*]] = aie.buffer(%[[TILE_3_3]]) {sym_name = "objfifo_cons_buff_1"} : memref<16xi32> -// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i32, sym_name = "objfifo_cons_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i32, sym_name = "objfifo_cons_cons_lock"} +// CHECK: %[[OBJFIFO_CONS_PROD_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 0) {init = 2 : i8, sym_name = "objfifo_cons_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_CONS_LOCK:.*]] = aie.lock(%[[TILE_3_3]], 1) {init = 0 : i8, sym_name = "objfifo_cons_cons_lock"} // CHECK: %[[OBJFIFO_BUFF_0:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_0"} : memref<16xi32> // CHECK: %[[OBJFIFO_BUFF_1:.*]] = aie.buffer(%[[TILE_1_2]]) {sym_name = "objfifo_buff_1"} : memref<16xi32> -// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 2 : i32, sym_name = "objfifo_prod_lock"} -// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 4) {init = 0 : i32, sym_name = "objfifo_cons_lock"} +// CHECK: %[[OBJFIFO_PROD_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 3) {init = 2 : i8, sym_name = "objfifo_prod_lock"} +// CHECK: %[[OBJFIFO_CONS_LOCK:.*]] = aie.lock(%[[TILE_1_2]], 4) {init = 0 : i8, sym_name = "objfifo_cons_lock"} // CHECK: %[[BUFFER_1_2:.*]] = aie.buffer(%[[TILE_1_2]]) : memref<16xi32> // CHECK: %[[LOCK_1_2:.*]] = aie.lock(%[[TILE_1_2]], 0) // CHECK: %[[BUFFER_1_2_0:.*]] = aie.buffer(%[[TILE_1_2]]) : memref<16xi32> diff --git a/compiler/plugins/target/AMD-AIE/aie/test/trace_packet_routing.mlir b/compiler/plugins/target/AMD-AIE/aie/test/trace_packet_routing.mlir index 39987c746..76d55e212 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/trace_packet_routing.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/trace_packet_routing.mlir @@ -10,11 +10,11 @@ module @trace_packet_routing { %tile_0_3 = aie.tile(0, 3) aie.packet_flow(0) { - aie.packet_source<%tile_0_2, Trace : 0> // core trace + aie.packet_source<%tile_0_2, TRACE : 0> // core trace aie.packet_dest<%tile_0_0, DMA : 1> } {keep_pkt_header = true} aie.packet_flow(1) { - aie.packet_source<%tile_0_3, Trace : 0> // core trace + aie.packet_source<%tile_0_3, TRACE : 0> // core trace aie.packet_dest<%tile_1_0, DMA : 1> } {keep_pkt_header = true} } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_broadcast.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_broadcast.mlir index 14a872b4e..be1d885b7 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_broadcast.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_broadcast.mlir @@ -21,113 +21,113 @@ // CHECK: %[[TILE_8_2:.*]] = aie.tile(8, 2) // CHECK: %[[TILE_8_3:.*]] = aie.tile(8, 3) // CHECK: %[[SWITCHBOX_1_3:.*]] = aie.switchbox(%[[TILE_1_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_0:.*]] = aie.tile(4, 0) // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_0:.*]] = aie.tile(5, 0) // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_1:.*]] = aie.tile(6, 1) // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_2:.*]] = aie.tile(6, 2) // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_0_1:.*]] = aie.tile(0, 1) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_2:.*]] = aie.tile(3, 2) // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_2:.*]] = aie.tile(4, 2) // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_fixed_connections.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_fixed_connections.mlir index 9241a8735..df9fb8eec 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_fixed_connections.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_fixed_connections.mlir @@ -7,20 +7,20 @@ // CHECK: %[[TILE_6_0:.*]] = aie.tile(6, 0) // CHECK: %[[TILE_7_0:.*]] = aie.tile(7, 0) // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -31,20 +31,20 @@ module { %tile_6_0 = aie.tile(6, 0) %tile_7_0 = aie.tile(7, 0) %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_3_0 = aie.switchbox(%tile_3_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_6_0 = aie.switchbox(%tile_6_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_0 = aie.switchbox(%tile_7_0) { - aie.connect - aie.connect + aie.connect + aie.connect } } } @@ -63,38 +63,38 @@ module { // CHECK: %[[TILE_10_2:.*]] = aie.tile(10, 2) // CHECK: %[[TILE_11_3:.*]] = aie.tile(11, 3) // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_4:.*]] = aie.switchbox(%[[TILE_1_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_4:.*]] = aie.switchbox(%[[TILE_7_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_2:.*]] = aie.switchbox(%[[TILE_9_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_2:.*]] = aie.switchbox(%[[TILE_10_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_3:.*]] = aie.switchbox(%[[TILE_11_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -111,38 +111,38 @@ module { %tile_10_2 = aie.tile(10, 2) %tile_11_3 = aie.tile(11, 3) %switchbox_0_3 = aie.switchbox(%tile_0_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_1_4 = aie.switchbox(%tile_1_4) { - aie.connect + aie.connect } %switchbox_3_3 = aie.switchbox(%tile_3_3) { - aie.connect + aie.connect } %switchbox_4_2 = aie.switchbox(%tile_4_2) { - aie.connect + aie.connect } %switchbox_5_3 = aie.switchbox(%tile_5_3) { - aie.connect + aie.connect } %switchbox_6_3 = aie.switchbox(%tile_6_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_4 = aie.switchbox(%tile_7_4) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_9_2 = aie.switchbox(%tile_9_2) { - aie.connect + aie.connect } %switchbox_10_2 = aie.switchbox(%tile_10_2) { - aie.connect + aie.connect } %switchbox_11_3 = aie.switchbox(%tile_11_3) { - aie.connect - aie.connect + aie.connect + aie.connect } } } @@ -157,28 +157,28 @@ module { // CHECK: %[[TILE_12_5:.*]] = aie.tile(12, 5) // CHECK: %[[TILE_13_3:.*]] = aie.tile(13, 3) // CHECK: %[[SWITCHBOX_2_5:.*]] = aie.switchbox(%[[TILE_2_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_6:.*]] = aie.switchbox(%[[TILE_6_6]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_12_5:.*]] = aie.switchbox(%[[TILE_12_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_3:.*]] = aie.switchbox(%[[TILE_13_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -191,28 +191,28 @@ module { %tile_12_5 = aie.tile(12, 5) %tile_13_3 = aie.tile(13, 3) %switchbox_2_5 = aie.switchbox(%tile_2_5) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_3_1 = aie.switchbox(%tile_3_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_6_6 = aie.switchbox(%tile_6_6) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_3 = aie.switchbox(%tile_7_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_12_5 = aie.switchbox(%tile_12_5) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_13_3 = aie.switchbox(%tile_13_3) { - aie.connect - aie.connect + aie.connect + aie.connect } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_1.mlir index 3f208ec6e..891b6b360 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_1.mlir @@ -15,269 +15,269 @@ // CHECK: %[[TILE_8_3:.*]] = aie.tile(8, 3) // CHECK: %[[TILE_8_4:.*]] = aie.tile(8, 4) // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_2:.*]] = aie.tile(3, 2) // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_2:.*]] = aie.tile(4, 2) // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_2:.*]] = aie.tile(5, 2) // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_3:.*]] = aie.tile(5, 3) // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_7_3:.*]] = aie.tile(7, 3) // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_0:.*]] = aie.tile(4, 0) // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_0:.*]] = aie.tile(5, 0) // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_1:.*]] = aie.tile(6, 1) // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_2:.*]] = aie.tile(6, 2) // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_1:.*]] = aie.tile(3, 1) // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_4:.*]] = aie.switchbox(%[[TILE_5_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_4:.*]] = aie.switchbox(%[[TILE_3_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_4:.*]] = aie.switchbox(%[[TILE_4_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_4:.*]] = aie.tile(6, 4) // CHECK: %[[SWITCHBOX_6_4:.*]] = aie.switchbox(%[[TILE_6_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_7_4:.*]] = aie.tile(7, 4) // CHECK: %[[SWITCHBOX_7_4:.*]] = aie.switchbox(%[[TILE_7_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_4:.*]] = aie.switchbox(%[[TILE_8_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_7_1:.*]] = aie.tile(7, 1) // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_8_0:.*]] = aie.tile(8, 0) // CHECK: %[[SWITCHBOX_8_0:.*]] = aie.switchbox(%[[TILE_8_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_8_1:.*]] = aie.tile(8, 1) // CHECK: %[[SWITCHBOX_8_1:.*]] = aie.switchbox(%[[TILE_8_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_8_2:.*]] = aie.tile(8, 2) // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -299,25 +299,25 @@ module { aie.flow(%t20, DMA : 1, %t83, DMA : 0) aie.flow(%t30, DMA : 0, %t72, DMA : 0) aie.flow(%t30, DMA : 1, %t54, DMA : 0) - aie.flow(%t34, Core : 0, %t63, Core : 1) + aie.flow(%t34, CORE : 0, %t63, CORE : 1) aie.flow(%t34, DMA : 1, %t70, DMA : 0) - aie.flow(%t43, Core : 0, %t84, Core : 1) + aie.flow(%t43, CORE : 0, %t84, CORE : 1) aie.flow(%t43, DMA : 1, %t60, DMA : 1) - aie.flow(%t44, Core : 0, %t54, Core : 1) + aie.flow(%t44, CORE : 0, %t54, CORE : 1) aie.flow(%t44, DMA : 1, %t60, DMA : 0) - aie.flow(%t54, Core : 0, %t43, Core : 1) + aie.flow(%t54, CORE : 0, %t43, CORE : 1) aie.flow(%t54, DMA : 1, %t30, DMA : 1) aie.flow(%t60, DMA : 0, %t44, DMA : 0) aie.flow(%t60, DMA : 1, %t43, DMA : 0) - aie.flow(%t63, Core : 0, %t34, Core : 1) + aie.flow(%t63, CORE : 0, %t34, CORE : 1) aie.flow(%t63, DMA : 1, %t20, DMA : 1) aie.flow(%t70, DMA : 0, %t34, DMA : 0) aie.flow(%t70, DMA : 1, %t84, DMA : 0) - aie.flow(%t72, Core : 0, %t83, Core : 1) + aie.flow(%t72, CORE : 0, %t83, CORE : 1) aie.flow(%t72, DMA : 1, %t30, DMA : 0) - aie.flow(%t83, Core : 0, %t44, Core : 1) + aie.flow(%t83, CORE : 0, %t44, CORE : 1) aie.flow(%t83, DMA : 1, %t20, DMA : 0) - aie.flow(%t84, Core : 0, %t72, Core : 1) + aie.flow(%t84, CORE : 0, %t72, CORE : 1) aie.flow(%t84, DMA : 1, %t70, DMA : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_2.mlir index bb106fb4f..fecc0ac20 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_2.mlir @@ -22,127 +22,127 @@ // CHECK: %[[TILE_3_4:.*]] = aie.tile(3, 4) // CHECK: %[[TILE_1_0:.*]] = aie.tile(1, 0) // CHECK: %[[SWITCHBOX_1_0:.*]] = aie.switchbox(%[[TILE_1_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_2:.*]] = aie.switchbox(%[[TILE_1_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_4:.*]] = aie.switchbox(%[[TILE_1_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_4:.*]] = aie.switchbox(%[[TILE_2_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_4:.*]] = aie.switchbox(%[[TILE_0_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_3:.*]] = aie.switchbox(%[[TILE_1_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_4:.*]] = aie.switchbox(%[[TILE_3_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -168,30 +168,30 @@ module { %t34 = aie.tile(3, 4) //TASK 1 aie.flow(%t20, DMA : 0, %t11, DMA : 0) - aie.flow(%t11, Core : 0, %t01, Core : 0) - aie.flow(%t01, Core : 0, %t12, Core : 0) - aie.flow(%t12, Core : 0, %t02, Core : 0) + aie.flow(%t11, CORE : 0, %t01, CORE : 0) + aie.flow(%t01, CORE : 0, %t12, CORE : 0) + aie.flow(%t12, CORE : 0, %t02, CORE : 0) aie.flow(%t02, DMA : 0, %t20, DMA : 0) //TASK 2 aie.flow(%t20, DMA : 1, %t14, DMA : 0) - aie.flow(%t14, Core : 0, %t04, Core : 0) - aie.flow(%t04, Core : 0, %t13, Core : 0) + aie.flow(%t14, CORE : 0, %t04, CORE : 0) + aie.flow(%t04, CORE : 0, %t13, CORE : 0) aie.flow(%t13, DMA : 0, %t20, DMA : 1) //TASK 3 aie.flow(%t30, DMA : 0, %t21, DMA : 0) - aie.flow(%t21, Core : 0, %t33, Core : 0) - aie.flow(%t33, Core : 0, %t22, Core : 0) - aie.flow(%t22, Core : 0, %t34, Core : 0) - aie.flow(%t34, Core : 0, %t24, Core : 0) - aie.flow(%t24, Core : 0, %t23, Core : 0) + aie.flow(%t21, CORE : 0, %t33, CORE : 0) + aie.flow(%t33, CORE : 0, %t22, CORE : 0) + aie.flow(%t22, CORE : 0, %t34, CORE : 0) + aie.flow(%t34, CORE : 0, %t24, CORE : 0) + aie.flow(%t24, CORE : 0, %t23, CORE : 0) aie.flow(%t23, DMA : 0, %t30, DMA : 0) //TASK 4 aie.flow(%t30, DMA : 1, %t31, DMA : 1) - aie.flow(%t31, Core : 1, %t23, Core : 1) - aie.flow(%t23, Core : 1, %t34, Core : 1) - aie.flow(%t34, Core : 1, %t24, Core : 1) - aie.flow(%t24, Core : 1, %t33, Core : 1) - aie.flow(%t33, Core : 1, %t32, Core : 1) + aie.flow(%t31, CORE : 1, %t23, CORE : 1) + aie.flow(%t23, CORE : 1, %t34, CORE : 1) + aie.flow(%t34, CORE : 1, %t24, CORE : 1) + aie.flow(%t24, CORE : 1, %t33, CORE : 1) + aie.flow(%t33, CORE : 1, %t32, CORE : 1) aie.flow(%t32, DMA : 1, %t30, DMA : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_3.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_3.mlir index 1472867df..d94ba7178 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_3.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_flow_test_3.mlir @@ -25,268 +25,268 @@ // CHECK: %[[TILE_8_3:.*]] = aie.tile(8, 3) // CHECK: %[[TILE_8_4:.*]] = aie.tile(8, 4) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_1_0:.*]] = aie.tile(1, 0) // CHECK: %[[SWITCHBOX_1_0:.*]] = aie.switchbox(%[[TILE_1_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_3:.*]] = aie.switchbox(%[[TILE_1_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_3:.*]] = aie.tile(4, 3) // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_3:.*]] = aie.tile(5, 3) // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_3:.*]] = aie.tile(6, 3) // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_4:.*]] = aie.switchbox(%[[TILE_8_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_1:.*]] = aie.tile(3, 1) // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_2:.*]] = aie.tile(4, 2) // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_4:.*]] = aie.tile(4, 4) // CHECK: %[[SWITCHBOX_4_4:.*]] = aie.switchbox(%[[TILE_4_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_4:.*]] = aie.tile(5, 4) // CHECK: %[[SWITCHBOX_5_4:.*]] = aie.switchbox(%[[TILE_5_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_4:.*]] = aie.tile(6, 4) // CHECK: %[[SWITCHBOX_6_4:.*]] = aie.switchbox(%[[TILE_6_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_4:.*]] = aie.switchbox(%[[TILE_7_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_2:.*]] = aie.switchbox(%[[TILE_1_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_4:.*]] = aie.switchbox(%[[TILE_2_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_4:.*]] = aie.switchbox(%[[TILE_1_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_1:.*]] = aie.tile(6, 1) // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_2:.*]] = aie.tile(6, 2) // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_2:.*]] = aie.tile(3, 2) // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_2:.*]] = aie.tile(5, 2) // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_4:.*]] = aie.switchbox(%[[TILE_0_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_4:.*]] = aie.tile(3, 4) // CHECK: %[[SWITCHBOX_3_4:.*]] = aie.switchbox(%[[TILE_3_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -316,27 +316,27 @@ module { %t84 = aie.tile(8, 4) //TASK 1 aie.flow(%t20, DMA : 0, %t03, DMA : 0) - aie.flow(%t03, Core : 0, %t71, Core : 0) - aie.flow(%t71, Core : 0, %t84, Core : 0) - aie.flow(%t84, Core : 0, %t11, Core : 0) - aie.flow(%t11, Core : 0, %t24, Core : 0) + aie.flow(%t03, CORE : 0, %t71, CORE : 0) + aie.flow(%t71, CORE : 0, %t84, CORE : 0) + aie.flow(%t84, CORE : 0, %t11, CORE : 0) + aie.flow(%t11, CORE : 0, %t24, CORE : 0) aie.flow(%t24, DMA : 0, %t20, DMA : 0) //TASK 2 aie.flow(%t30, DMA : 0, %t14, DMA : 0) - aie.flow(%t14, Core : 0, %t01, Core : 0) - aie.flow(%t01, Core : 0, %t83, Core : 0) - aie.flow(%t83, Core : 0, %t21, Core : 0) - aie.flow(%t21, Core : 0, %t73, Core : 0) - aie.flow(%t73, Core : 0, %t82, Core : 0) + aie.flow(%t14, CORE : 0, %t01, CORE : 0) + aie.flow(%t01, CORE : 0, %t83, CORE : 0) + aie.flow(%t83, CORE : 0, %t21, CORE : 0) + aie.flow(%t21, CORE : 0, %t73, CORE : 0) + aie.flow(%t73, CORE : 0, %t82, CORE : 0) aie.flow(%t82, DMA : 0, %t30, DMA : 0) //TASK 3 aie.flow(%t20, DMA : 1, %t83, DMA : 1) - aie.flow(%t83, Core : 1, %t01, Core : 1) - aie.flow(%t01, Core : 1, %t72, Core : 1) - aie.flow(%t72, Core : 1, %t02, Core : 1) - aie.flow(%t02, Core : 1, %t24, Core : 1) - aie.flow(%t24, Core : 1, %t71, Core : 1) - aie.flow(%t71, Core : 1, %t84, Core : 1) + aie.flow(%t83, CORE : 1, %t01, CORE : 1) + aie.flow(%t01, CORE : 1, %t72, CORE : 1) + aie.flow(%t72, CORE : 1, %t02, CORE : 1) + aie.flow(%t02, CORE : 1, %t24, CORE : 1) + aie.flow(%t24, CORE : 1, %t71, CORE : 1) + aie.flow(%t71, CORE : 1, %t84, CORE : 1) aie.flow(%t84, DMA : 1, %t20, DMA : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows.mlir index 2696ff627..bbaa18045 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows.mlir @@ -14,182 +14,182 @@ // CHECK: %[[TILE_7_0:.*]] = aie.tile(7, 0) // CHECK: %[[TILE_7_3:.*]] = aie.tile(7, 3) // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_1_2:.*]] = aie.tile(1, 2) // CHECK: %[[SWITCHBOX_1_2:.*]] = aie.switchbox(%[[TILE_1_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_1:.*]] = aie.tile(6, 1) // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_3:.*]] = aie.switchbox(%[[TILE_1_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_3:.*]] = aie.tile(4, 3) // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_3:.*]] = aie.tile(5, 3) // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_2:.*]] = aie.tile(6, 2) // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_3:.*]] = aie.tile(6, 3) // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_0_1:.*]] = aie.tile(0, 1) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_1_0:.*]] = aie.tile(1, 0) // CHECK: %[[SWITCHBOX_1_0:.*]] = aie.switchbox(%[[TILE_1_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_0:.*]] = aie.tile(4, 0) // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_0:.*]] = aie.tile(5, 0) // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_2:.*]] = aie.tile(3, 2) // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_2:.*]] = aie.tile(4, 2) // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_2:.*]] = aie.tile(5, 2) // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_7_2:.*]] = aie.tile(7, 2) // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -210,15 +210,15 @@ module { aie.flow(%t13, DMA : 0, %t70, DMA : 1) aie.flow(%t02, DMA : 0, %t60, DMA : 0) aie.flow(%t22, DMA : 0, %t60, DMA : 1) - aie.flow(%t03, Core : 0, %t13, Core : 0) - aie.flow(%t03, Core : 1, %t02, Core : 0) - aie.flow(%t13, Core : 1, %t22, Core : 0) - aie.flow(%t02, Core : 1, %t22, Core : 1) + aie.flow(%t03, CORE : 0, %t13, CORE : 0) + aie.flow(%t03, CORE : 1, %t02, CORE : 0) + aie.flow(%t13, CORE : 1, %t22, CORE : 0) + aie.flow(%t02, CORE : 1, %t22, CORE : 1) aie.flow(%t73, DMA : 0, %t20, DMA : 0) aie.flow(%t73, DMA : 1, %t30, DMA : 0) aie.flow(%t31, DMA : 0, %t20, DMA : 1) aie.flow(%t31, DMA : 1, %t30, DMA : 1) - aie.flow(%t73, Core : 0, %t31, Core : 0) - aie.flow(%t73, Core : 1, %t31, Core : 1) + aie.flow(%t73, CORE : 0, %t31, CORE : 0) + aie.flow(%t73, CORE : 1, %t31, CORE : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows2.mlir index 6aa08e0a9..9c004d4e7 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_many_flows2.mlir @@ -14,166 +14,166 @@ // CHECK: %[[TILE_7_0:.*]] = aie.tile(7, 0) // CHECK: %[[TILE_7_3:.*]] = aie.tile(7, 3) // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_1_2:.*]] = aie.tile(1, 2) // CHECK: %[[SWITCHBOX_1_2:.*]] = aie.switchbox(%[[TILE_1_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_1:.*]] = aie.tile(6, 1) // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_0_1:.*]] = aie.tile(0, 1) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_1_0:.*]] = aie.tile(1, 0) // CHECK: %[[SWITCHBOX_1_0:.*]] = aie.switchbox(%[[TILE_1_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_0:.*]] = aie.tile(4, 0) // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_0:.*]] = aie.tile(5, 0) // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_3:.*]] = aie.switchbox(%[[TILE_1_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_2:.*]] = aie.tile(5, 2) // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_2:.*]] = aie.tile(6, 2) // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_7_2:.*]] = aie.tile(7, 2) // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_3:.*]] = aie.tile(4, 3) // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_3:.*]] = aie.tile(5, 3) // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_3:.*]] = aie.tile(6, 3) // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_7_1:.*]] = aie.tile(7, 1) // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -194,15 +194,15 @@ module { aie.flow(%t03, DMA : 1, %t70, DMA : 1) aie.flow(%t02, DMA : 0, %t60, DMA : 0) aie.flow(%t22, DMA : 0, %t20, DMA : 0) - aie.flow(%t22, Core : 0, %t13, Core : 0) - aie.flow(%t03, Core : 1, %t02, Core : 0) - aie.flow(%t73, Core : 0, %t31, Core : 0) - aie.flow(%t73, Core : 1, %t22, Core : 1) + aie.flow(%t22, CORE : 0, %t13, CORE : 0) + aie.flow(%t03, CORE : 1, %t02, CORE : 0) + aie.flow(%t73, CORE : 0, %t31, CORE : 0) + aie.flow(%t73, CORE : 1, %t22, CORE : 1) aie.flow(%t73, DMA : 0, %t60, DMA : 1) aie.flow(%t73, DMA : 1, %t70, DMA : 0) aie.flow(%t31, DMA : 0, %t20, DMA : 1) aie.flow(%t31, DMA : 1, %t30, DMA : 1) - aie.flow(%t03, Core : 0, %t02, Core : 1) - aie.flow(%t13, Core : 1, %t31, Core : 1) + aie.flow(%t03, CORE : 0, %t02, CORE : 1) + aie.flow(%t13, CORE : 1, %t31, CORE : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile.mlir index 5a4b0301f..b34ab15ca 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile.mlir @@ -7,40 +7,40 @@ // CHECK: %[[TILE_0_2:.*]] = aie.tile(0, 2) // CHECK: %[[TILE_0_1:.*]] = aie.tile(0, 1) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_4:.*]] = aie.switchbox(%[[TILE_0_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile_routing_constraints.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile_routing_constraints.mlir index fb7a7a310..f78673091 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile_routing_constraints.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_memtile_routing_constraints.mlir @@ -7,21 +7,21 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_mmult.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_mmult.mlir index 5e654e530..d459a67c8 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_mmult.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_mmult.mlir @@ -166,172 +166,172 @@ // CHECK: aie.end // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_2:.*]] = aie.tile(4, 2) // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_2:.*]] = aie.tile(5, 2) // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_3_3:.*]] = aie.tile(3, 3) // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_3:.*]] = aie.tile(4, 3) // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_3:.*]] = aie.tile(5, 3) // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_3:.*]] = aie.tile(6, 3) // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -501,64 +501,64 @@ module @aie.herd_0 { aie.end } %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } - aie.flow(%tile_2_1, South : 0, %tile_7_2, DMA : 0) - aie.flow(%tile_2_1, South : 1, %tile_7_2, DMA : 1) - aie.flow(%tile_7_2, DMA : 0, %tile_2_1, South : 0) + aie.flow(%tile_2_1, SOUTH : 0, %tile_7_2, DMA : 0) + aie.flow(%tile_2_1, SOUTH : 1, %tile_7_2, DMA : 1) + aie.flow(%tile_7_2, DMA : 0, %tile_2_1, SOUTH : 0) %switchbox_3_0 = aie.switchbox(%tile_3_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } - aie.flow(%tile_3_1, South : 0, %tile_8_2, DMA : 0) - aie.flow(%tile_3_1, South : 1, %tile_8_2, DMA : 1) - aie.flow(%tile_8_2, DMA : 0, %tile_2_1, South : 1) + aie.flow(%tile_3_1, SOUTH : 0, %tile_8_2, DMA : 0) + aie.flow(%tile_3_1, SOUTH : 1, %tile_8_2, DMA : 1) + aie.flow(%tile_8_2, DMA : 0, %tile_2_1, SOUTH : 1) %switchbox_6_0 = aie.switchbox(%tile_6_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } - aie.flow(%tile_6_1, South : 0, %tile_7_3, DMA : 0) - aie.flow(%tile_6_1, South : 1, %tile_7_3, DMA : 1) - aie.flow(%tile_7_3, DMA : 0, %tile_3_1, South : 0) + aie.flow(%tile_6_1, SOUTH : 0, %tile_7_3, DMA : 0) + aie.flow(%tile_6_1, SOUTH : 1, %tile_7_3, DMA : 1) + aie.flow(%tile_7_3, DMA : 0, %tile_3_1, SOUTH : 0) %switchbox_7_0 = aie.switchbox(%tile_7_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } - aie.flow(%tile_7_1, South : 0, %tile_8_3, DMA : 0) - aie.flow(%tile_7_1, South : 1, %tile_8_3, DMA : 1) - aie.flow(%tile_8_3, DMA : 0, %tile_3_1, South : 1) + aie.flow(%tile_7_1, SOUTH : 0, %tile_8_3, DMA : 0) + aie.flow(%tile_7_1, SOUTH : 1, %tile_8_3, DMA : 1) + aie.flow(%tile_8_3, DMA : 0, %tile_3_1, SOUTH : 1) %shimmux_2_0 = aie.shim_mux(%tile_2_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %shimmux_3_0 = aie.shim_mux(%tile_3_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %shimmux_6_0 = aie.shim_mux(%tile_6_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %shimmux_7_0 = aie.shim_mux(%tile_7_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_over_flows.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_over_flows.mlir index 23362e1a1..64e10669b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_over_flows.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_over_flows.mlir @@ -21,103 +21,103 @@ // CHECK: %[[TILE_8_2:.*]] = aie.tile(8, 2) // CHECK: %[[TILE_8_3:.*]] = aie.tile(8, 3) // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_1:.*]] = aie.tile(4, 1) // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_1:.*]] = aie.tile(5, 1) // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_1:.*]] = aie.tile(6, 1) // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_0:.*]] = aie.tile(4, 0) // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_6_2:.*]] = aie.tile(6, 2) // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x1.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x1.mlir index a969e9aa3..7c201f0a8 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x1.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x1.mlir @@ -69,102 +69,102 @@ // CHECK: %[[TILE_12_3:.*]] = aie.tile(12, 3) // CHECK: %[[TILE_12_4:.*]] = aie.tile(12, 4) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_3:.*]] = aie.switchbox(%[[TILE_0_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_4:.*]] = aie.switchbox(%[[TILE_0_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_2:.*]] = aie.switchbox(%[[TILE_1_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_3:.*]] = aie.switchbox(%[[TILE_1_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_4:.*]] = aie.switchbox(%[[TILE_1_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_4:.*]] = aie.switchbox(%[[TILE_2_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_4:.*]] = aie.switchbox(%[[TILE_3_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { // CHECK: } // CHECK: %[[SWITCHBOX_4_4:.*]] = aie.switchbox(%[[TILE_4_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_4:.*]] = aie.switchbox(%[[TILE_5_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_3:.*]] = aie.switchbox(%[[TILE_6_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_4:.*]] = aie.switchbox(%[[TILE_6_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_4:.*]] = aie.switchbox(%[[TILE_7_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_1:.*]] = aie.switchbox(%[[TILE_8_1]]) { // CHECK: } @@ -175,193 +175,193 @@ // CHECK: %[[SWITCHBOX_8_4:.*]] = aie.switchbox(%[[TILE_8_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_9_1:.*]] = aie.switchbox(%[[TILE_9_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_2:.*]] = aie.switchbox(%[[TILE_9_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_3:.*]] = aie.switchbox(%[[TILE_9_3]]) { // CHECK: } // CHECK: %[[SWITCHBOX_9_4:.*]] = aie.switchbox(%[[TILE_9_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_10_1:.*]] = aie.switchbox(%[[TILE_10_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_2:.*]] = aie.switchbox(%[[TILE_10_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_3:.*]] = aie.switchbox(%[[TILE_10_3]]) { // CHECK: } // CHECK: %[[SWITCHBOX_10_4:.*]] = aie.switchbox(%[[TILE_10_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_11_1:.*]] = aie.switchbox(%[[TILE_11_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_2:.*]] = aie.switchbox(%[[TILE_11_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_3:.*]] = aie.switchbox(%[[TILE_11_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_4:.*]] = aie.switchbox(%[[TILE_11_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_0:.*]] = aie.switchbox(%[[TILE_0_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_0:.*]] = aie.switchbox(%[[TILE_1_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_0:.*]] = aie.switchbox(%[[TILE_10_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_10_0:.*]] = aie.shim_mux(%[[TILE_10_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_0:.*]] = aie.switchbox(%[[TILE_11_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_11_0:.*]] = aie.shim_mux(%[[TILE_11_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_0:.*]] = aie.switchbox(%[[TILE_8_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_0:.*]] = aie.switchbox(%[[TILE_9_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_0:.*]] = aie.tile(12, 0) // CHECK: %[[SWITCHBOX_12_0:.*]] = aie.switchbox(%[[TILE_12_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_0:.*]] = aie.tile(13, 0) // CHECK: %[[SWITCHBOX_13_0:.*]] = aie.switchbox(%[[TILE_13_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_0:.*]] = aie.tile(14, 0) // CHECK: %[[SWITCHBOX_14_0:.*]] = aie.switchbox(%[[TILE_14_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_0:.*]] = aie.tile(15, 0) // CHECK: %[[SWITCHBOX_15_0:.*]] = aie.switchbox(%[[TILE_15_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_0:.*]] = aie.tile(16, 0) // CHECK: %[[SWITCHBOX_16_0:.*]] = aie.switchbox(%[[TILE_16_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_0:.*]] = aie.tile(17, 0) // CHECK: %[[SWITCHBOX_17_0:.*]] = aie.switchbox(%[[TILE_17_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_18_0:.*]] = aie.switchbox(%[[TILE_18_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_18_0:.*]] = aie.shim_mux(%[[TILE_18_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_19_0:.*]] = aie.switchbox(%[[TILE_19_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_19_0:.*]] = aie.shim_mux(%[[TILE_19_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -434,102 +434,102 @@ module { %tile_12_3 = aie.tile(12, 3) %tile_12_4 = aie.tile(12, 4) %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect + aie.connect } %switchbox_0_3 = aie.switchbox(%tile_0_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_4 = aie.switchbox(%tile_0_4) { } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect + aie.connect } %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect + aie.connect } %switchbox_1_3 = aie.switchbox(%tile_1_3) { - aie.connect + aie.connect } %switchbox_1_4 = aie.switchbox(%tile_1_4) { - aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect + aie.connect } %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect + aie.connect } %switchbox_2_3 = aie.switchbox(%tile_2_3) { - aie.connect + aie.connect } %switchbox_2_4 = aie.switchbox(%tile_2_4) { - aie.connect + aie.connect } %switchbox_3_1 = aie.switchbox(%tile_3_1) { - aie.connect + aie.connect } %switchbox_3_2 = aie.switchbox(%tile_3_2) { - aie.connect + aie.connect } %switchbox_3_3 = aie.switchbox(%tile_3_3) { - aie.connect + aie.connect } %switchbox_3_4 = aie.switchbox(%tile_3_4) { } %switchbox_4_1 = aie.switchbox(%tile_4_1) { - aie.connect + aie.connect } %switchbox_4_2 = aie.switchbox(%tile_4_2) { - aie.connect + aie.connect } %switchbox_4_3 = aie.switchbox(%tile_4_3) { } %switchbox_4_4 = aie.switchbox(%tile_4_4) { } %switchbox_5_1 = aie.switchbox(%tile_5_1) { - aie.connect + aie.connect } %switchbox_5_2 = aie.switchbox(%tile_5_2) { - aie.connect + aie.connect } %switchbox_5_3 = aie.switchbox(%tile_5_3) { - aie.connect + aie.connect } %switchbox_5_4 = aie.switchbox(%tile_5_4) { } %switchbox_6_1 = aie.switchbox(%tile_6_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_6_2 = aie.switchbox(%tile_6_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_6_3 = aie.switchbox(%tile_6_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_6_4 = aie.switchbox(%tile_6_4) { } %switchbox_7_1 = aie.switchbox(%tile_7_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_2 = aie.switchbox(%tile_7_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_3 = aie.switchbox(%tile_7_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_4 = aie.switchbox(%tile_7_4) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_8_1 = aie.switchbox(%tile_8_1) { } @@ -540,52 +540,52 @@ module { %switchbox_8_4 = aie.switchbox(%tile_8_4) { } %switchbox_9_1 = aie.switchbox(%tile_9_1) { - aie.connect + aie.connect } %switchbox_9_2 = aie.switchbox(%tile_9_2) { - aie.connect + aie.connect } %switchbox_9_3 = aie.switchbox(%tile_9_3) { } %switchbox_9_4 = aie.switchbox(%tile_9_4) { } %switchbox_10_1 = aie.switchbox(%tile_10_1) { - aie.connect + aie.connect } %switchbox_10_2 = aie.switchbox(%tile_10_2) { - aie.connect + aie.connect } %switchbox_10_3 = aie.switchbox(%tile_10_3) { } %switchbox_10_4 = aie.switchbox(%tile_10_4) { } %switchbox_11_1 = aie.switchbox(%tile_11_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_11_2 = aie.switchbox(%tile_11_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_11_3 = aie.switchbox(%tile_11_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_11_4 = aie.switchbox(%tile_11_4) { } - aie.flow(%tile_2_0, DMA : 0, %tile_2_0, North : 0) - aie.flow(%tile_2_0, DMA : 1, %tile_6_0, North : 1) - aie.flow(%tile_3_0, DMA : 0, %tile_3_0, North : 0) - aie.flow(%tile_3_0, DMA : 1, %tile_7_0, North : 1) - aie.flow(%tile_6_0, DMA : 0, %tile_0_0, North : 0) - aie.flow(%tile_6_0, DMA : 1, %tile_4_0, North : 0) - aie.flow(%tile_7_0, DMA : 0, %tile_1_0, North : 0) - aie.flow(%tile_7_0, DMA : 1, %tile_5_0, North : 0) - aie.flow(%tile_10_0, DMA : 0, %tile_10_0, North : 0) - aie.flow(%tile_11_0, DMA : 0, %tile_11_0, North : 0) - aie.flow(%tile_18_0, DMA : 0, %tile_6_0, North : 0) - aie.flow(%tile_18_0, DMA : 1, %tile_9_0, North : 0) - aie.flow(%tile_19_0, DMA : 0, %tile_7_0, North : 0) - aie.flow(%tile_19_0, DMA : 1, %tile_11_0, North : 1) + aie.flow(%tile_2_0, DMA : 0, %tile_2_0, NORTH : 0) + aie.flow(%tile_2_0, DMA : 1, %tile_6_0, NORTH : 1) + aie.flow(%tile_3_0, DMA : 0, %tile_3_0, NORTH : 0) + aie.flow(%tile_3_0, DMA : 1, %tile_7_0, NORTH : 1) + aie.flow(%tile_6_0, DMA : 0, %tile_0_0, NORTH : 0) + aie.flow(%tile_6_0, DMA : 1, %tile_4_0, NORTH : 0) + aie.flow(%tile_7_0, DMA : 0, %tile_1_0, NORTH : 0) + aie.flow(%tile_7_0, DMA : 1, %tile_5_0, NORTH : 0) + aie.flow(%tile_10_0, DMA : 0, %tile_10_0, NORTH : 0) + aie.flow(%tile_11_0, DMA : 0, %tile_11_0, NORTH : 0) + aie.flow(%tile_18_0, DMA : 0, %tile_6_0, NORTH : 0) + aie.flow(%tile_18_0, DMA : 1, %tile_9_0, NORTH : 0) + aie.flow(%tile_19_0, DMA : 0, %tile_7_0, NORTH : 0) + aie.flow(%tile_19_0, DMA : 1, %tile_11_0, NORTH : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x2.mlir index bb23793dc..3bf5d867b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_routed_herd_3x2.mlir @@ -154,56 +154,56 @@ // CHECK: %[[SWITCHBOX_1_4:.*]] = aie.switchbox(%[[TILE_1_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { // CHECK: } // CHECK: %[[SWITCHBOX_2_4:.*]] = aie.switchbox(%[[TILE_2_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_5:.*]] = aie.switchbox(%[[TILE_2_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_3:.*]] = aie.switchbox(%[[TILE_3_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_4:.*]] = aie.switchbox(%[[TILE_3_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_5:.*]] = aie.switchbox(%[[TILE_3_5]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_1:.*]] = aie.switchbox(%[[TILE_4_1]]) { // CHECK: } // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_3:.*]] = aie.switchbox(%[[TILE_4_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_4:.*]] = aie.switchbox(%[[TILE_4_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_1:.*]] = aie.switchbox(%[[TILE_5_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_3:.*]] = aie.switchbox(%[[TILE_5_3]]) { // CHECK: } @@ -212,7 +212,7 @@ // CHECK: %[[SWITCHBOX_5_5:.*]] = aie.switchbox(%[[TILE_5_5]]) { // CHECK: } // CHECK: %[[SWITCHBOX_5_6:.*]] = aie.switchbox(%[[TILE_5_6]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { // CHECK: } @@ -225,32 +225,32 @@ // CHECK: %[[SWITCHBOX_6_5:.*]] = aie.switchbox(%[[TILE_6_5]]) { // CHECK: } // CHECK: %[[SWITCHBOX_6_6:.*]] = aie.switchbox(%[[TILE_6_6]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_4:.*]] = aie.switchbox(%[[TILE_7_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_5:.*]] = aie.switchbox(%[[TILE_7_5]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_6:.*]] = aie.switchbox(%[[TILE_7_6]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_1:.*]] = aie.switchbox(%[[TILE_8_1]]) { // CHECK: } // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_4:.*]] = aie.switchbox(%[[TILE_8_4]]) { // CHECK: } @@ -259,18 +259,18 @@ // CHECK: %[[SWITCHBOX_9_2:.*]] = aie.switchbox(%[[TILE_9_2]]) { // CHECK: } // CHECK: %[[SWITCHBOX_9_3:.*]] = aie.switchbox(%[[TILE_9_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_4:.*]] = aie.switchbox(%[[TILE_9_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_10_1:.*]] = aie.switchbox(%[[TILE_10_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_2:.*]] = aie.switchbox(%[[TILE_10_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_3:.*]] = aie.switchbox(%[[TILE_10_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_4:.*]] = aie.switchbox(%[[TILE_10_4]]) { // CHECK: } @@ -291,110 +291,110 @@ // CHECK: %[[SWITCHBOX_12_4:.*]] = aie.switchbox(%[[TILE_12_4]]) { // CHECK: } // CHECK: %[[SWITCHBOX_12_5:.*]] = aie.switchbox(%[[TILE_12_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_1:.*]] = aie.switchbox(%[[TILE_13_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_2:.*]] = aie.switchbox(%[[TILE_13_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_3:.*]] = aie.switchbox(%[[TILE_13_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_4:.*]] = aie.switchbox(%[[TILE_13_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_5:.*]] = aie.switchbox(%[[TILE_13_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_5:.*]] = aie.switchbox(%[[TILE_4_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_0:.*]] = aie.switchbox(%[[TILE_10_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_10_0:.*]] = aie.shim_mux(%[[TILE_10_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_4_6:.*]] = aie.switchbox(%[[TILE_4_6]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_0:.*]] = aie.switchbox(%[[TILE_11_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_11_0:.*]] = aie.shim_mux(%[[TILE_11_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_0:.*]] = aie.tile(12, 0) // CHECK: %[[SWITCHBOX_12_0:.*]] = aie.switchbox(%[[TILE_12_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_13_0:.*]] = aie.switchbox(%[[TILE_13_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_14_2:.*]] = aie.switchbox(%[[TILE_14_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_14_3:.*]] = aie.switchbox(%[[TILE_14_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_14_4:.*]] = aie.switchbox(%[[TILE_14_4]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_14_5:.*]] = aie.switchbox(%[[TILE_14_5]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_2:.*]] = aie.tile(15, 2) // CHECK: %[[SWITCHBOX_15_2:.*]] = aie.switchbox(%[[TILE_15_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_2:.*]] = aie.tile(16, 2) // CHECK: %[[SWITCHBOX_16_2:.*]] = aie.switchbox(%[[TILE_16_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_0:.*]] = aie.tile(17, 0) // CHECK: %[[SWITCHBOX_17_0:.*]] = aie.switchbox(%[[TILE_17_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_1:.*]] = aie.tile(17, 1) // CHECK: %[[SWITCHBOX_17_1:.*]] = aie.switchbox(%[[TILE_17_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_2:.*]] = aie.tile(17, 2) // CHECK: %[[SWITCHBOX_17_2:.*]] = aie.switchbox(%[[TILE_17_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_18_0:.*]] = aie.switchbox(%[[TILE_18_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_18_0:.*]] = aie.shim_mux(%[[TILE_18_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -558,27 +558,27 @@ module { %switchbox_2_3 = aie.switchbox(%tile_2_3) { } %switchbox_2_4 = aie.switchbox(%tile_2_4) { - aie.connect + aie.connect } %switchbox_2_5 = aie.switchbox(%tile_2_5) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_3_1 = aie.switchbox(%tile_3_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_3_2 = aie.switchbox(%tile_3_2) { - aie.connect + aie.connect } %switchbox_3_3 = aie.switchbox(%tile_3_3) { - aie.connect + aie.connect } %switchbox_3_4 = aie.switchbox(%tile_3_4) { - aie.connect + aie.connect } %switchbox_3_5 = aie.switchbox(%tile_3_5) { - aie.connect + aie.connect } %switchbox_4_1 = aie.switchbox(%tile_4_1) { } @@ -599,7 +599,7 @@ module { %switchbox_5_5 = aie.switchbox(%tile_5_5) { } %switchbox_5_6 = aie.switchbox(%tile_5_6) { - aie.connect + aie.connect } %switchbox_6_1 = aie.switchbox(%tile_6_1) { } @@ -612,32 +612,32 @@ module { %switchbox_6_5 = aie.switchbox(%tile_6_5) { } %switchbox_6_6 = aie.switchbox(%tile_6_6) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_1 = aie.switchbox(%tile_7_1) { } %switchbox_7_2 = aie.switchbox(%tile_7_2) { } %switchbox_7_3 = aie.switchbox(%tile_7_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_7_4 = aie.switchbox(%tile_7_4) { - aie.connect + aie.connect } %switchbox_7_5 = aie.switchbox(%tile_7_5) { - aie.connect + aie.connect } %switchbox_7_6 = aie.switchbox(%tile_7_6) { - aie.connect + aie.connect } %switchbox_8_1 = aie.switchbox(%tile_8_1) { } %switchbox_8_2 = aie.switchbox(%tile_8_2) { } %switchbox_8_3 = aie.switchbox(%tile_8_3) { - aie.connect + aie.connect } %switchbox_8_4 = aie.switchbox(%tile_8_4) { } @@ -674,31 +674,31 @@ module { %switchbox_12_4 = aie.switchbox(%tile_12_4) { } %switchbox_12_5 = aie.switchbox(%tile_12_5) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_13_1 = aie.switchbox(%tile_13_1) { - aie.connect + aie.connect } %switchbox_13_2 = aie.switchbox(%tile_13_2) { - aie.connect + aie.connect } %switchbox_13_3 = aie.switchbox(%tile_13_3) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_13_4 = aie.switchbox(%tile_13_4) { - aie.connect + aie.connect } %switchbox_13_5 = aie.switchbox(%tile_13_5) { - aie.connect - aie.connect - } - aie.flow(%tile_3_0, DMA : 0, %tile_3_0, North : 0) - aie.flow(%tile_4_5, West : 0, %tile_6_0, DMA : 0) - aie.flow(%tile_10_0, DMA : 0, %tile_9_3, West : 0) - aie.flow(%tile_4_6, East : 0, %tile_2_0, DMA : 0) - aie.flow(%tile_11_0, DMA : 0, %tile_13_0, North : 0) - aie.flow(%tile_14_5, West : 0, %tile_18_0, DMA : 0) + aie.connect + aie.connect + } + aie.flow(%tile_3_0, DMA : 0, %tile_3_0, NORTH : 0) + aie.flow(%tile_4_5, WEST : 0, %tile_6_0, DMA : 0) + aie.flow(%tile_10_0, DMA : 0, %tile_9_3, WEST : 0) + aie.flow(%tile_4_6, EAST : 0, %tile_2_0, DMA : 0) + aie.flow(%tile_11_0, DMA : 0, %tile_13_0, NORTH : 0) + aie.flow(%tile_14_5, WEST : 0, %tile_18_0, DMA : 0) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple.mlir index 833fc77e7..20c7ddfbf 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple.mlir @@ -6,17 +6,17 @@ // CHECK: %[[TILE_1_2:.*]] = aie.tile(1, 2) // CHECK: %[[TILE_0_2:.*]] = aie.tile(0, 2) // CHECK: %[[SWITCHBOX_0_1:.*]] = aie.switchbox(%[[TILE_0_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_0_2:.*]] = aie.switchbox(%[[TILE_0_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_2:.*]] = aie.switchbox(%[[TILE_1_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: aie.packet_flow(16) { -// CHECK: aie.packet_source<%[[TILE_0_1]], Core : 0> -// CHECK: aie.packet_dest<%[[TILE_1_2]], Core : 0> +// CHECK: aie.packet_source<%[[TILE_0_1]], CORE : 0> +// CHECK: aie.packet_dest<%[[TILE_1_2]], CORE : 0> // CHECK: aie.packet_dest<%[[TILE_0_2]], DMA : 1> // CHECK: } // CHECK: } @@ -26,10 +26,10 @@ module { %01 = aie.tile(0, 1) %12 = aie.tile(1, 2) %02 = aie.tile(0, 2) - aie.flow(%01, DMA : 0, %12, Core : 1) + aie.flow(%01, DMA : 0, %12, CORE : 1) aie.packet_flow(0x10) { - aie.packet_source < %01, Core : 0> - aie.packet_dest < %12, Core : 0> + aie.packet_source < %01, CORE : 0> + aie.packet_dest < %12, CORE : 0> aie.packet_dest < %02, DMA : 1> } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple2.mlir index 9db838065..fa93123d7 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple2.mlir @@ -6,13 +6,13 @@ // CHECK: %[[TILE_3_2:.*]] = aie.tile(3, 2) // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -20,6 +20,6 @@ module { aie.device(xcvc1902) { %0 = aie.tile(2, 3) %1 = aie.tile(3, 2) - aie.flow(%0, Core : 1, %1, DMA : 0) + aie.flow(%0, CORE : 1, %1, DMA : 0) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows.mlir index 8b98d04cd..1e674a31e 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows.mlir @@ -5,13 +5,13 @@ // CHECK: %[[TILE_2_3:.*]] = aie.tile(2, 3) // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -19,8 +19,8 @@ module { aie.device(xcvc1902) { %t23 = aie.tile(2, 3) %t22 = aie.tile(2, 2) - aie.flow(%t23, Core : 0, %t22, Core : 1) - aie.flow(%t22, Core : 0, %t22, Core : 0) - aie.flow(%t22, Core : 1, %t23, Core : 1) + aie.flow(%t23, CORE : 0, %t22, CORE : 1) + aie.flow(%t22, CORE : 0, %t22, CORE : 0) + aie.flow(%t22, CORE : 1, %t23, CORE : 1) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows2.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows2.mlir index 524443a6e..3ed0acc32 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows2.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows2.mlir @@ -6,18 +6,18 @@ // CHECK: %[[TILE_2_2:.*]] = aie.tile(2, 2) // CHECK: %[[TILE_1_1:.*]] = aie.tile(1, 1) // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_3:.*]] = aie.switchbox(%[[TILE_2_3]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_1_1:.*]] = aie.switchbox(%[[TILE_1_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -26,7 +26,7 @@ module { %t23 = aie.tile(2, 3) %t22 = aie.tile(2, 2) %t11 = aie.tile(1, 1) - aie.flow(%t23, Core : 0, %t22, Core : 1) - aie.flow(%t22, Core : 0, %t11, Core : 0) + aie.flow(%t23, CORE : 0, %t22, CORE : 1) + aie.flow(%t22, CORE : 0, %t11, CORE : 0) } } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows_shim.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows_shim.mlir index 4ccabe4e1..102d18cf6 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows_shim.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_simple_flows_shim.mlir @@ -5,13 +5,13 @@ // CHECK: %[[TILE_2_0:.*]] = aie.tile(2, 0) // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } @@ -19,7 +19,7 @@ module { aie.device(xcvc1902) { %t20 = aie.tile(2, 0) %t21 = aie.tile(2, 1) - aie.flow(%t21, Core : 0, %t20, DMA : 1) + aie.flow(%t21, CORE : 0, %t20, DMA : 1) } } @@ -29,16 +29,16 @@ module { // CHECK: %[[TILE_2_0:.*]] = aie.tile(2, 0) // CHECK: %[[TILE_3_0:.*]] = aie.tile(3, 0) // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/unit_vecmul_4x4.mlir b/compiler/plugins/target/AMD-AIE/aie/test/unit_vecmul_4x4.mlir index 936eb6a73..3412f6a1c 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/unit_vecmul_4x4.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/unit_vecmul_4x4.mlir @@ -859,1452 +859,1452 @@ // CHECK: cf.br ^bb1 // CHECK: } // CHECK: %[[SWITCHBOX_2_0:.*]] = aie.switchbox(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_2_0:.*]] = aie.shim_mux(%[[TILE_2_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_1:.*]] = aie.switchbox(%[[TILE_2_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_2_2:.*]] = aie.switchbox(%[[TILE_2_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_2:.*]] = aie.switchbox(%[[TILE_3_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_2:.*]] = aie.tile(4, 2) // CHECK: %[[SWITCHBOX_4_2:.*]] = aie.switchbox(%[[TILE_4_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_2:.*]] = aie.tile(5, 2) // CHECK: %[[SWITCHBOX_5_2:.*]] = aie.switchbox(%[[TILE_5_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_2:.*]] = aie.switchbox(%[[TILE_6_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_2:.*]] = aie.switchbox(%[[TILE_7_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_0:.*]] = aie.switchbox(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_3_0:.*]] = aie.shim_mux(%[[TILE_3_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_4_0:.*]] = aie.tile(4, 0) // CHECK: %[[SWITCHBOX_4_0:.*]] = aie.switchbox(%[[TILE_4_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_5_0:.*]] = aie.tile(5, 0) // CHECK: %[[SWITCHBOX_5_0:.*]] = aie.switchbox(%[[TILE_5_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_0:.*]] = aie.switchbox(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_6_1:.*]] = aie.switchbox(%[[TILE_6_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_2:.*]] = aie.switchbox(%[[TILE_8_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_6_0:.*]] = aie.shim_mux(%[[TILE_6_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_0:.*]] = aie.switchbox(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_8_0:.*]] = aie.tile(8, 0) // CHECK: %[[SWITCHBOX_8_0:.*]] = aie.switchbox(%[[TILE_8_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_9_0:.*]] = aie.tile(9, 0) // CHECK: %[[SWITCHBOX_9_0:.*]] = aie.switchbox(%[[TILE_9_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_9_1:.*]] = aie.tile(9, 1) // CHECK: %[[SWITCHBOX_9_1:.*]] = aie.switchbox(%[[TILE_9_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_2:.*]] = aie.switchbox(%[[TILE_9_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_3_1:.*]] = aie.switchbox(%[[TILE_3_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_7_0:.*]] = aie.shim_mux(%[[TILE_7_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_0:.*]] = aie.switchbox(%[[TILE_10_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_1:.*]] = aie.switchbox(%[[TILE_10_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_2:.*]] = aie.switchbox(%[[TILE_10_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_3:.*]] = aie.switchbox(%[[TILE_7_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_8_1:.*]] = aie.tile(8, 1) // CHECK: %[[SWITCHBOX_8_1:.*]] = aie.switchbox(%[[TILE_8_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_3:.*]] = aie.switchbox(%[[TILE_8_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_10_0:.*]] = aie.shim_mux(%[[TILE_10_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_1:.*]] = aie.switchbox(%[[TILE_7_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_3:.*]] = aie.switchbox(%[[TILE_9_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_0:.*]] = aie.switchbox(%[[TILE_11_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_11_0:.*]] = aie.shim_mux(%[[TILE_11_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_3:.*]] = aie.switchbox(%[[TILE_10_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_0:.*]] = aie.tile(12, 0) // CHECK: %[[SWITCHBOX_12_0:.*]] = aie.switchbox(%[[TILE_12_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_0:.*]] = aie.tile(13, 0) // CHECK: %[[SWITCHBOX_13_0:.*]] = aie.switchbox(%[[TILE_13_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_0:.*]] = aie.tile(14, 0) // CHECK: %[[SWITCHBOX_14_0:.*]] = aie.switchbox(%[[TILE_14_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_0:.*]] = aie.tile(15, 0) // CHECK: %[[SWITCHBOX_15_0:.*]] = aie.switchbox(%[[TILE_15_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_0:.*]] = aie.tile(16, 0) // CHECK: %[[SWITCHBOX_16_0:.*]] = aie.switchbox(%[[TILE_16_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_0:.*]] = aie.tile(17, 0) // CHECK: %[[SWITCHBOX_17_0:.*]] = aie.switchbox(%[[TILE_17_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_18_0:.*]] = aie.switchbox(%[[TILE_18_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_18_0:.*]] = aie.shim_mux(%[[TILE_18_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_1:.*]] = aie.switchbox(%[[TILE_11_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_11_2:.*]] = aie.switchbox(%[[TILE_11_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_11_3:.*]] = aie.tile(11, 3) // CHECK: %[[SWITCHBOX_11_3:.*]] = aie.switchbox(%[[TILE_11_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_19_0:.*]] = aie.switchbox(%[[TILE_19_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_19_0:.*]] = aie.shim_mux(%[[TILE_19_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_4:.*]] = aie.switchbox(%[[TILE_7_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_1:.*]] = aie.tile(12, 1) // CHECK: %[[SWITCHBOX_12_1:.*]] = aie.switchbox(%[[TILE_12_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_1:.*]] = aie.tile(13, 1) // CHECK: %[[SWITCHBOX_13_1:.*]] = aie.switchbox(%[[TILE_13_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_1:.*]] = aie.tile(14, 1) // CHECK: %[[SWITCHBOX_14_1:.*]] = aie.switchbox(%[[TILE_14_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_1:.*]] = aie.tile(15, 1) // CHECK: %[[SWITCHBOX_15_1:.*]] = aie.switchbox(%[[TILE_15_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_1:.*]] = aie.tile(16, 1) // CHECK: %[[SWITCHBOX_16_1:.*]] = aie.switchbox(%[[TILE_16_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_1:.*]] = aie.tile(17, 1) // CHECK: %[[SWITCHBOX_17_1:.*]] = aie.switchbox(%[[TILE_17_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_18_1:.*]] = aie.switchbox(%[[TILE_18_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_20_0:.*]] = aie.tile(20, 0) // CHECK: %[[SWITCHBOX_20_0:.*]] = aie.switchbox(%[[TILE_20_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_21_0:.*]] = aie.tile(21, 0) // CHECK: %[[SWITCHBOX_21_0:.*]] = aie.switchbox(%[[TILE_21_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_22_0:.*]] = aie.tile(22, 0) // CHECK: %[[SWITCHBOX_22_0:.*]] = aie.switchbox(%[[TILE_22_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_23_0:.*]] = aie.tile(23, 0) // CHECK: %[[SWITCHBOX_23_0:.*]] = aie.switchbox(%[[TILE_23_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_24_0:.*]] = aie.tile(24, 0) // CHECK: %[[SWITCHBOX_24_0:.*]] = aie.switchbox(%[[TILE_24_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_25_0:.*]] = aie.tile(25, 0) // CHECK: %[[SWITCHBOX_25_0:.*]] = aie.switchbox(%[[TILE_25_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_26_0:.*]] = aie.switchbox(%[[TILE_26_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_26_0:.*]] = aie.shim_mux(%[[TILE_26_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_4:.*]] = aie.switchbox(%[[TILE_8_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_4:.*]] = aie.switchbox(%[[TILE_9_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_19_1:.*]] = aie.switchbox(%[[TILE_19_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_27_0:.*]] = aie.switchbox(%[[TILE_27_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_27_0:.*]] = aie.shim_mux(%[[TILE_27_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_2:.*]] = aie.tile(12, 2) // CHECK: %[[SWITCHBOX_12_2:.*]] = aie.switchbox(%[[TILE_12_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_2:.*]] = aie.tile(13, 2) // CHECK: %[[SWITCHBOX_13_2:.*]] = aie.switchbox(%[[TILE_13_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_2:.*]] = aie.tile(14, 2) // CHECK: %[[SWITCHBOX_14_2:.*]] = aie.switchbox(%[[TILE_14_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_2:.*]] = aie.tile(15, 2) // CHECK: %[[SWITCHBOX_15_2:.*]] = aie.switchbox(%[[TILE_15_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_2:.*]] = aie.tile(16, 2) // CHECK: %[[SWITCHBOX_16_2:.*]] = aie.switchbox(%[[TILE_16_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_2:.*]] = aie.tile(17, 2) // CHECK: %[[SWITCHBOX_17_2:.*]] = aie.switchbox(%[[TILE_17_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_18_2:.*]] = aie.switchbox(%[[TILE_18_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_19_2:.*]] = aie.switchbox(%[[TILE_19_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_20_1:.*]] = aie.tile(20, 1) // CHECK: %[[SWITCHBOX_20_1:.*]] = aie.switchbox(%[[TILE_20_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_20_2:.*]] = aie.tile(20, 2) // CHECK: %[[SWITCHBOX_20_2:.*]] = aie.switchbox(%[[TILE_20_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_21_1:.*]] = aie.tile(21, 1) // CHECK: %[[SWITCHBOX_21_1:.*]] = aie.switchbox(%[[TILE_21_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_22_1:.*]] = aie.tile(22, 1) // CHECK: %[[SWITCHBOX_22_1:.*]] = aie.switchbox(%[[TILE_22_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_23_1:.*]] = aie.tile(23, 1) // CHECK: %[[SWITCHBOX_23_1:.*]] = aie.switchbox(%[[TILE_23_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_24_1:.*]] = aie.tile(24, 1) // CHECK: %[[SWITCHBOX_24_1:.*]] = aie.switchbox(%[[TILE_24_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_25_1:.*]] = aie.tile(25, 1) // CHECK: %[[SWITCHBOX_25_1:.*]] = aie.switchbox(%[[TILE_25_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_26_1:.*]] = aie.switchbox(%[[TILE_26_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_28_0:.*]] = aie.tile(28, 0) // CHECK: %[[SWITCHBOX_28_0:.*]] = aie.switchbox(%[[TILE_28_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_29_0:.*]] = aie.tile(29, 0) // CHECK: %[[SWITCHBOX_29_0:.*]] = aie.switchbox(%[[TILE_29_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_30_0:.*]] = aie.tile(30, 0) // CHECK: %[[SWITCHBOX_30_0:.*]] = aie.switchbox(%[[TILE_30_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_31_0:.*]] = aie.tile(31, 0) // CHECK: %[[SWITCHBOX_31_0:.*]] = aie.switchbox(%[[TILE_31_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_32_0:.*]] = aie.tile(32, 0) // CHECK: %[[SWITCHBOX_32_0:.*]] = aie.switchbox(%[[TILE_32_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_33_0:.*]] = aie.tile(33, 0) // CHECK: %[[SWITCHBOX_33_0:.*]] = aie.switchbox(%[[TILE_33_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_34_0:.*]] = aie.switchbox(%[[TILE_34_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_34_0:.*]] = aie.shim_mux(%[[TILE_34_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_4:.*]] = aie.switchbox(%[[TILE_10_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_3:.*]] = aie.tile(12, 3) // CHECK: %[[SWITCHBOX_12_3:.*]] = aie.switchbox(%[[TILE_12_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_3:.*]] = aie.tile(13, 3) // CHECK: %[[SWITCHBOX_13_3:.*]] = aie.switchbox(%[[TILE_13_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_3:.*]] = aie.tile(14, 3) // CHECK: %[[SWITCHBOX_14_3:.*]] = aie.switchbox(%[[TILE_14_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_3:.*]] = aie.tile(15, 3) // CHECK: %[[SWITCHBOX_15_3:.*]] = aie.switchbox(%[[TILE_15_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_3:.*]] = aie.tile(16, 3) // CHECK: %[[SWITCHBOX_16_3:.*]] = aie.switchbox(%[[TILE_16_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_3:.*]] = aie.tile(17, 3) // CHECK: %[[SWITCHBOX_17_3:.*]] = aie.switchbox(%[[TILE_17_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_18_3:.*]] = aie.tile(18, 3) // CHECK: %[[SWITCHBOX_18_3:.*]] = aie.switchbox(%[[TILE_18_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_19_3:.*]] = aie.tile(19, 3) // CHECK: %[[SWITCHBOX_19_3:.*]] = aie.switchbox(%[[TILE_19_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_20_3:.*]] = aie.tile(20, 3) // CHECK: %[[SWITCHBOX_20_3:.*]] = aie.switchbox(%[[TILE_20_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_27_1:.*]] = aie.switchbox(%[[TILE_27_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_35_0:.*]] = aie.switchbox(%[[TILE_35_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_35_0:.*]] = aie.shim_mux(%[[TILE_35_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_7_5:.*]] = aie.switchbox(%[[TILE_7_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_8_5:.*]] = aie.switchbox(%[[TILE_8_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_9_5:.*]] = aie.switchbox(%[[TILE_9_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_10_5:.*]] = aie.switchbox(%[[TILE_10_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_11_5:.*]] = aie.tile(11, 5) // CHECK: %[[SWITCHBOX_11_5:.*]] = aie.switchbox(%[[TILE_11_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_5:.*]] = aie.tile(12, 5) // CHECK: %[[SWITCHBOX_12_5:.*]] = aie.switchbox(%[[TILE_12_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_5:.*]] = aie.tile(13, 5) // CHECK: %[[SWITCHBOX_13_5:.*]] = aie.switchbox(%[[TILE_13_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_5:.*]] = aie.tile(14, 5) // CHECK: %[[SWITCHBOX_14_5:.*]] = aie.switchbox(%[[TILE_14_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_4:.*]] = aie.tile(15, 4) // CHECK: %[[SWITCHBOX_15_4:.*]] = aie.switchbox(%[[TILE_15_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_15_5:.*]] = aie.tile(15, 5) // CHECK: %[[SWITCHBOX_15_5:.*]] = aie.switchbox(%[[TILE_15_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_21_3:.*]] = aie.tile(21, 3) // CHECK: %[[SWITCHBOX_21_3:.*]] = aie.switchbox(%[[TILE_21_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_22_3:.*]] = aie.tile(22, 3) // CHECK: %[[SWITCHBOX_22_3:.*]] = aie.switchbox(%[[TILE_22_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_23_3:.*]] = aie.tile(23, 3) // CHECK: %[[SWITCHBOX_23_3:.*]] = aie.switchbox(%[[TILE_23_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_24_2:.*]] = aie.tile(24, 2) // CHECK: %[[SWITCHBOX_24_2:.*]] = aie.switchbox(%[[TILE_24_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_24_3:.*]] = aie.tile(24, 3) // CHECK: %[[SWITCHBOX_24_3:.*]] = aie.switchbox(%[[TILE_24_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_25_2:.*]] = aie.tile(25, 2) // CHECK: %[[SWITCHBOX_25_2:.*]] = aie.switchbox(%[[TILE_25_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_26_2:.*]] = aie.switchbox(%[[TILE_26_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_28_1:.*]] = aie.tile(28, 1) // CHECK: %[[SWITCHBOX_28_1:.*]] = aie.switchbox(%[[TILE_28_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_29_1:.*]] = aie.tile(29, 1) // CHECK: %[[SWITCHBOX_29_1:.*]] = aie.switchbox(%[[TILE_29_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_30_1:.*]] = aie.tile(30, 1) // CHECK: %[[SWITCHBOX_30_1:.*]] = aie.switchbox(%[[TILE_30_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_31_1:.*]] = aie.tile(31, 1) // CHECK: %[[SWITCHBOX_31_1:.*]] = aie.switchbox(%[[TILE_31_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_32_1:.*]] = aie.tile(32, 1) // CHECK: %[[SWITCHBOX_32_1:.*]] = aie.switchbox(%[[TILE_32_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_33_1:.*]] = aie.tile(33, 1) // CHECK: %[[SWITCHBOX_33_1:.*]] = aie.switchbox(%[[TILE_33_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_34_1:.*]] = aie.switchbox(%[[TILE_34_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_36_0:.*]] = aie.tile(36, 0) // CHECK: %[[SWITCHBOX_36_0:.*]] = aie.switchbox(%[[TILE_36_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_37_0:.*]] = aie.tile(37, 0) // CHECK: %[[SWITCHBOX_37_0:.*]] = aie.switchbox(%[[TILE_37_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_38_0:.*]] = aie.tile(38, 0) // CHECK: %[[SWITCHBOX_38_0:.*]] = aie.switchbox(%[[TILE_38_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_39_0:.*]] = aie.tile(39, 0) // CHECK: %[[SWITCHBOX_39_0:.*]] = aie.switchbox(%[[TILE_39_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_40_0:.*]] = aie.tile(40, 0) // CHECK: %[[SWITCHBOX_40_0:.*]] = aie.switchbox(%[[TILE_40_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_41_0:.*]] = aie.tile(41, 0) // CHECK: %[[SWITCHBOX_41_0:.*]] = aie.switchbox(%[[TILE_41_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_42_0:.*]] = aie.switchbox(%[[TILE_42_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_42_0:.*]] = aie.shim_mux(%[[TILE_42_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_11_4:.*]] = aie.tile(11, 4) // CHECK: %[[SWITCHBOX_11_4:.*]] = aie.switchbox(%[[TILE_11_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_12_4:.*]] = aie.tile(12, 4) // CHECK: %[[SWITCHBOX_12_4:.*]] = aie.switchbox(%[[TILE_12_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_13_4:.*]] = aie.tile(13, 4) // CHECK: %[[SWITCHBOX_13_4:.*]] = aie.switchbox(%[[TILE_13_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_14_4:.*]] = aie.tile(14, 4) // CHECK: %[[SWITCHBOX_14_4:.*]] = aie.switchbox(%[[TILE_14_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_4:.*]] = aie.tile(16, 4) // CHECK: %[[SWITCHBOX_16_4:.*]] = aie.switchbox(%[[TILE_16_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_4:.*]] = aie.tile(17, 4) // CHECK: %[[SWITCHBOX_17_4:.*]] = aie.switchbox(%[[TILE_17_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_21_2:.*]] = aie.tile(21, 2) // CHECK: %[[SWITCHBOX_21_2:.*]] = aie.switchbox(%[[TILE_21_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_22_2:.*]] = aie.tile(22, 2) // CHECK: %[[SWITCHBOX_22_2:.*]] = aie.switchbox(%[[TILE_22_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_23_2:.*]] = aie.tile(23, 2) // CHECK: %[[SWITCHBOX_23_2:.*]] = aie.switchbox(%[[TILE_23_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_27_2:.*]] = aie.switchbox(%[[TILE_27_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_35_1:.*]] = aie.switchbox(%[[TILE_35_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_43_0:.*]] = aie.switchbox(%[[TILE_43_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_43_0:.*]] = aie.shim_mux(%[[TILE_43_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_18_4:.*]] = aie.tile(18, 4) // CHECK: %[[SWITCHBOX_18_4:.*]] = aie.switchbox(%[[TILE_18_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_19_4:.*]] = aie.tile(19, 4) // CHECK: %[[SWITCHBOX_19_4:.*]] = aie.switchbox(%[[TILE_19_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_20_4:.*]] = aie.tile(20, 4) // CHECK: %[[SWITCHBOX_20_4:.*]] = aie.switchbox(%[[TILE_20_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_25_3:.*]] = aie.tile(25, 3) // CHECK: %[[SWITCHBOX_25_3:.*]] = aie.switchbox(%[[TILE_25_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_26_3:.*]] = aie.tile(26, 3) // CHECK: %[[SWITCHBOX_26_3:.*]] = aie.switchbox(%[[TILE_26_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_28_2:.*]] = aie.tile(28, 2) // CHECK: %[[SWITCHBOX_28_2:.*]] = aie.switchbox(%[[TILE_28_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_29_2:.*]] = aie.tile(29, 2) // CHECK: %[[SWITCHBOX_29_2:.*]] = aie.switchbox(%[[TILE_29_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_30_2:.*]] = aie.tile(30, 2) // CHECK: %[[SWITCHBOX_30_2:.*]] = aie.switchbox(%[[TILE_30_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_31_2:.*]] = aie.tile(31, 2) // CHECK: %[[SWITCHBOX_31_2:.*]] = aie.switchbox(%[[TILE_31_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_32_2:.*]] = aie.tile(32, 2) // CHECK: %[[SWITCHBOX_32_2:.*]] = aie.switchbox(%[[TILE_32_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_33_2:.*]] = aie.tile(33, 2) // CHECK: %[[SWITCHBOX_33_2:.*]] = aie.switchbox(%[[TILE_33_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_34_2:.*]] = aie.switchbox(%[[TILE_34_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_35_2:.*]] = aie.switchbox(%[[TILE_35_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_36_2:.*]] = aie.tile(36, 2) // CHECK: %[[SWITCHBOX_36_2:.*]] = aie.switchbox(%[[TILE_36_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_37_2:.*]] = aie.tile(37, 2) // CHECK: %[[SWITCHBOX_37_2:.*]] = aie.switchbox(%[[TILE_37_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_38_2:.*]] = aie.tile(38, 2) // CHECK: %[[SWITCHBOX_38_2:.*]] = aie.switchbox(%[[TILE_38_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_39_2:.*]] = aie.tile(39, 2) // CHECK: %[[SWITCHBOX_39_2:.*]] = aie.switchbox(%[[TILE_39_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_40_2:.*]] = aie.tile(40, 2) // CHECK: %[[SWITCHBOX_40_2:.*]] = aie.switchbox(%[[TILE_40_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_41_1:.*]] = aie.tile(41, 1) // CHECK: %[[SWITCHBOX_41_1:.*]] = aie.switchbox(%[[TILE_41_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_41_2:.*]] = aie.tile(41, 2) // CHECK: %[[SWITCHBOX_41_2:.*]] = aie.switchbox(%[[TILE_41_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_42_1:.*]] = aie.switchbox(%[[TILE_42_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_44_0:.*]] = aie.tile(44, 0) // CHECK: %[[SWITCHBOX_44_0:.*]] = aie.switchbox(%[[TILE_44_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_45_0:.*]] = aie.tile(45, 0) // CHECK: %[[SWITCHBOX_45_0:.*]] = aie.switchbox(%[[TILE_45_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_46_0:.*]] = aie.switchbox(%[[TILE_46_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_46_0:.*]] = aie.shim_mux(%[[TILE_46_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_16_5:.*]] = aie.tile(16, 5) // CHECK: %[[SWITCHBOX_16_5:.*]] = aie.switchbox(%[[TILE_16_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_17_5:.*]] = aie.tile(17, 5) // CHECK: %[[SWITCHBOX_17_5:.*]] = aie.switchbox(%[[TILE_17_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_18_5:.*]] = aie.tile(18, 5) // CHECK: %[[SWITCHBOX_18_5:.*]] = aie.switchbox(%[[TILE_18_5]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_21_4:.*]] = aie.tile(21, 4) // CHECK: %[[SWITCHBOX_21_4:.*]] = aie.switchbox(%[[TILE_21_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_22_4:.*]] = aie.tile(22, 4) // CHECK: %[[SWITCHBOX_22_4:.*]] = aie.switchbox(%[[TILE_22_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_23_4:.*]] = aie.tile(23, 4) // CHECK: %[[SWITCHBOX_23_4:.*]] = aie.switchbox(%[[TILE_23_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_24_4:.*]] = aie.tile(24, 4) // CHECK: %[[SWITCHBOX_24_4:.*]] = aie.switchbox(%[[TILE_24_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_25_4:.*]] = aie.tile(25, 4) // CHECK: %[[SWITCHBOX_25_4:.*]] = aie.switchbox(%[[TILE_25_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_26_4:.*]] = aie.tile(26, 4) // CHECK: %[[SWITCHBOX_26_4:.*]] = aie.switchbox(%[[TILE_26_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_27_4:.*]] = aie.tile(27, 4) // CHECK: %[[SWITCHBOX_27_4:.*]] = aie.switchbox(%[[TILE_27_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_28_4:.*]] = aie.tile(28, 4) // CHECK: %[[SWITCHBOX_28_4:.*]] = aie.switchbox(%[[TILE_28_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_29_4:.*]] = aie.tile(29, 4) // CHECK: %[[SWITCHBOX_29_4:.*]] = aie.switchbox(%[[TILE_29_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_30_4:.*]] = aie.tile(30, 4) // CHECK: %[[SWITCHBOX_30_4:.*]] = aie.switchbox(%[[TILE_30_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_31_4:.*]] = aie.tile(31, 4) // CHECK: %[[SWITCHBOX_31_4:.*]] = aie.switchbox(%[[TILE_31_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_32_4:.*]] = aie.tile(32, 4) // CHECK: %[[SWITCHBOX_32_4:.*]] = aie.switchbox(%[[TILE_32_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_33_4:.*]] = aie.tile(33, 4) // CHECK: %[[SWITCHBOX_33_4:.*]] = aie.switchbox(%[[TILE_33_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_34_4:.*]] = aie.tile(34, 4) // CHECK: %[[SWITCHBOX_34_4:.*]] = aie.switchbox(%[[TILE_34_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_35_4:.*]] = aie.tile(35, 4) // CHECK: %[[SWITCHBOX_35_4:.*]] = aie.switchbox(%[[TILE_35_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_36_4:.*]] = aie.tile(36, 4) // CHECK: %[[SWITCHBOX_36_4:.*]] = aie.switchbox(%[[TILE_36_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_37_4:.*]] = aie.tile(37, 4) // CHECK: %[[SWITCHBOX_37_4:.*]] = aie.switchbox(%[[TILE_37_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_38_4:.*]] = aie.tile(38, 4) // CHECK: %[[SWITCHBOX_38_4:.*]] = aie.switchbox(%[[TILE_38_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_39_4:.*]] = aie.tile(39, 4) // CHECK: %[[SWITCHBOX_39_4:.*]] = aie.switchbox(%[[TILE_39_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_40_4:.*]] = aie.tile(40, 4) // CHECK: %[[SWITCHBOX_40_4:.*]] = aie.switchbox(%[[TILE_40_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_41_4:.*]] = aie.tile(41, 4) // CHECK: %[[SWITCHBOX_41_4:.*]] = aie.switchbox(%[[TILE_41_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_42_3:.*]] = aie.tile(42, 3) // CHECK: %[[SWITCHBOX_42_3:.*]] = aie.switchbox(%[[TILE_42_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_42_4:.*]] = aie.tile(42, 4) // CHECK: %[[SWITCHBOX_42_4:.*]] = aie.switchbox(%[[TILE_42_4]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_43_3:.*]] = aie.tile(43, 3) // CHECK: %[[SWITCHBOX_43_3:.*]] = aie.switchbox(%[[TILE_43_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_44_3:.*]] = aie.tile(44, 3) // CHECK: %[[SWITCHBOX_44_3:.*]] = aie.switchbox(%[[TILE_44_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_45_2:.*]] = aie.tile(45, 2) // CHECK: %[[SWITCHBOX_45_2:.*]] = aie.switchbox(%[[TILE_45_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[TILE_45_3:.*]] = aie.tile(45, 3) // CHECK: %[[SWITCHBOX_45_3:.*]] = aie.switchbox(%[[TILE_45_3]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_46_1:.*]] = aie.switchbox(%[[TILE_46_1]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_46_2:.*]] = aie.switchbox(%[[TILE_46_2]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SWITCHBOX_47_0:.*]] = aie.switchbox(%[[TILE_47_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: %[[SHIM_MUX_47_0:.*]] = aie.shim_mux(%[[TILE_47_0]]) { -// CHECK-DAG: aie.connect -// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect +// CHECK-DAG: aie.connect // CHECK: } // CHECK: } diff --git a/compiler/plugins/target/AMD-AIE/aie/test/user_assigned.mlir b/compiler/plugins/target/AMD-AIE/aie/test/user_assigned.mlir index 6272e334b..a95df956b 100644 --- a/compiler/plugins/target/AMD-AIE/aie/test/user_assigned.mlir +++ b/compiler/plugins/target/AMD-AIE/aie/test/user_assigned.mlir @@ -5,9 +5,9 @@ // CHECK: %[[TILE_2_1:.*]] = aie.tile(2, 1) // CHECK: %[[IN:.*]] = aie.buffer(%[[TILE_2_1]]) {address = 8192 : i32, sym_name = "in"} : memref<16xi32> // CHECK: %[[OUT:.*]] = aie.buffer(%[[TILE_2_1]]) {address = 1824 : i32, sym_name = "out"} : memref<16xi32> -// CHECK: %[[LOCK_2_1:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 1 : i32} +// CHECK: %[[LOCK_2_1:.*]] = aie.lock(%[[TILE_2_1]], 0) {init = 1 : i8} // CHECK: %[[LOCK_2_1_0:.*]] = aie.lock(%[[TILE_2_1]], 1) -// CHECK: %[[LOCK_2_1_1:.*]] = aie.lock(%[[TILE_2_1]], 2) {init = 1 : i32} +// CHECK: %[[LOCK_2_1_1:.*]] = aie.lock(%[[TILE_2_1]], 2) {init = 1 : i8} // CHECK: %[[LOCK_2_1_2:.*]] = aie.lock(%[[TILE_2_1]], 3) // CHECK: %[[MEMTILE_DMA_2_1:.*]] = aie.memtile_dma(%[[TILE_2_1]]) { // CHECK: %[[VAL_0:.*]] = aie.dma_start(S2MM, 0, ^bb4, ^bb1) @@ -47,9 +47,9 @@ module @aie_module { %t01 = aie.tile(2, 1) %buf01_0 = aie.buffer(%t01) { address = 8192 : i32, sym_name = "in" } : memref<16xi32> %buf01_1 = aie.buffer(%t01) { address = 1824 : i32, sym_name = "out" } : memref<16xi32> - %l01_0 = aie.lock(%t01, 0) { init = 1 : i32 } + %l01_0 = aie.lock(%t01, 0) { init = 1 : i8 } %l01_1 = aie.lock(%t01, 1) - %l01_2 = aie.lock(%t01, 2) { init = 1 : i32 } + %l01_2 = aie.lock(%t01, 2) { init = 1 : i8 } %l01_3 = aie.lock(%t01, 3) %m01 = aie.memtile_dma(%t01) { %srcDma = aie.dma_start(S2MM, 0, ^bd0, ^dma0) diff --git a/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt b/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt index d145d836c..61659076d 100644 --- a/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt +++ b/compiler/plugins/target/AMD-AIE/air/CMakeLists.txt @@ -183,20 +183,22 @@ iree_cc_library( replace_string_in_file( ${IREE_MLIR_AIR_SOURCE_DIR}/include/air/Conversion/PassDetail.h "aie/Dialect/AIEX/IR" "aie") - replace_string_in_file( - ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIESchedulingUtils.cpp - "target_model.getTargetArch()" "AIE::AIEArch::AIE2") -replace_string_in_file( - ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIESchedulingUtils.cpp - "AIE::WireBundle::DMA" "mlir::iree_compiler::AMDAIE::StrmSwPortType::DMA") - + ${IREE_MLIR_AIR_SOURCE_DIR}/include/air/Conversion/AIRToAIESchedulingUtils.h + "aie/Dialect/AIE/IR" "aie") replace_string_in_file( ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp - "target_model.getTargetArch()" "AIE::AIEArch::AIE2") + "aie/Dialect/AIE/IR" "aie") replace_string_in_file( - ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp - "device.getTargetModel().getTargetArch()" "AIE::AIEArch::AIE2") + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRLoweringPass.cpp + "aie/Dialect/AIE/IR" "aie") +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRRtToNpuPass.cpp + "aie/Dialect/AIEX/IR" "aie") + +replace_string_in_file( + ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIESchedulingUtils.cpp + "AIE::WireBundle::DMA" "mlir::iree_compiler::AMDAIE::StrmSwPortType::DMA") replace_string_in_file( ${IREE_MLIR_AIR_SOURCE_DIR}/lib/Conversion/AIRToAIEPass.cpp "AIE::AIETargetModel" "mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel") diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp index 5350f05b4..bfb24ecba 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Transforms/AMDAIEDistributeCoresAndObjectFifos.cpp @@ -671,12 +671,12 @@ LogicalResult assignLocalAieTiles(ModuleOp moduleOp) { tiles.reserve(tileLocations.size()); rewriter.setInsertionPoint(logicalObjectFifo); for (auto [column, row] : tileLocations) { - auto getCol = rewriter.create( + auto colIndex = rewriter.create( rewriter.getUnknownLoc(), column); - auto getRow = rewriter.create( + auto rowIndex = rewriter.create( rewriter.getUnknownLoc(), row); auto tileOp = rewriter.create( - rewriter.getUnknownLoc(), getCol, getRow); + rewriter.getUnknownLoc(), colIndex, rowIndex); tiles.push_back(tileOp.getResult()); } // Sort for deterministic output IR. diff --git a/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td b/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td index 8fd168ca1..4b0df4b44 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td +++ b/runtime/src/iree-amd-aie/aie_runtime/AMDAIEEnums.td @@ -10,7 +10,7 @@ include "mlir/IR/AttrTypeBase.td" include "mlir/IR/EnumAttr.td" -def AMDAIE_AMDAIEDevice: I32EnumAttr<"AMDAIEDevice", +def AMDAIEDeviceAttr: I32EnumAttr<"AMDAIEDevice", "Enum with target AMDAIE devices.", [ I32EnumAttrCase<"xcvc1902", 1>, @@ -36,4 +36,24 @@ def DMAChannelDir: I32EnumAttr<"DMAChannelDir", let cppNamespace = "mlir::iree_compiler::AMDAIE"; } +def StrmSwPortTypeAttr: I32EnumAttr<"StrmSwPortType", "", + [ + I32EnumAttrCase<"CORE", 0>, + I32EnumAttrCase<"DMA", 1>, + I32EnumAttrCase<"CTRL", 2>, + I32EnumAttrCase<"FIFO", 3>, + I32EnumAttrCase<"SOUTH", 4>, + I32EnumAttrCase<"WEST", 5>, + I32EnumAttrCase<"NORTH", 6>, + I32EnumAttrCase<"EAST", 7>, + I32EnumAttrCase<"TRACE", 8>, + I32EnumAttrCase<"UCTRLR", 9>, + I32EnumAttrCase<"SS_PORT_TYPE_MAX", 10>, + // "illegal" types after max + I32EnumAttrCase<"NOC", 11> + ]> +{ + let cppNamespace = "mlir::iree_compiler::AMDAIE"; +} + #endif // IREE_AIE_RUNTIME_AMDAIEENUMS diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc index 0dd0f4d06..969f0623b 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.cc @@ -440,9 +440,10 @@ uint32_t AMDAIEDeviceModel::getNumDestSwitchBoxConnections( return strmMod->MstrConfig[CheckedAieRtCompatStrmSwPortType(bundle)].NumPorts; } +// the difference between this fn and the one it calls is SwitchBox vs Switchbox uint32_t AMDAIEDeviceModel::getNumDestSwitchboxConnections( int col, int row, StrmSwPortType bundle) const { - return getNumDestSwitchboxConnections(static_cast(col), + return getNumDestSwitchBoxConnections(static_cast(col), static_cast(row), bundle); } @@ -556,7 +557,6 @@ struct AMDAIEDeviceModel getDeviceModel(AMDAIEDevice device) { std::string to_string(const int &value) { return std::to_string(value); } std::string to_string(const uint32_t &value) { return std::to_string(value); } std::string to_string(const uint64_t &value) { return std::to_string(value); } -std::string to_string(const size_t &value) { return std::to_string(value); } std::string to_string(const StrmSwPortType &value) { switch (value) { diff --git a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h index b8879147d..ebc049e2e 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h +++ b/runtime/src/iree-amd-aie/aie_runtime/iree_aie_runtime.h @@ -70,9 +70,9 @@ static_assert(static_cast(DMAChannelDir::MM2S) == struct SwitchDMAConnection { DMAChannelDir direction; - int channel; + uint8_t channel; - SwitchDMAConnection(DMAChannelDir direction, int channel) + SwitchDMAConnection(DMAChannelDir direction, uint8_t channel) : direction(direction), channel(channel) {} bool operator==(const SwitchDMAConnection& rhs) const { @@ -134,21 +134,10 @@ enum class AMDAIEDmaBdProp : uint8_t { MAX = sizeof(XAie_DmaBdProp) }; -enum class StrmSwPortType : uint8_t { - CORE = ::StrmSwPortType::CORE, - DMA, - CTRL, - FIFO, - SOUTH, - WEST, - NORTH, - EAST, - TRACE, - UCTRLR, - SS_PORT_TYPE_MAX, - // "illegal" types after max - NOC, -}; +static_assert(static_cast(StrmSwPortType::CORE) == + ::StrmSwPortType::CORE, + "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " + "aie-rt's StrmSwPortType"); static_assert(static_cast(StrmSwPortType::CORE) == 0, "mlir::iree_compiler::AMDAIE::StrmSwPortType is out of sync with " "aie-rt's StrmSwPortType"); @@ -199,6 +188,9 @@ inline ::XAie_TxnOpcode txnToTxn(XAie_TxnOpcode t) { return static_cast<::XAie_TxnOpcode>(t); } +// mlir-air legacy +enum class AIEArch : uint8_t { AIE1 = 1, AIE2 = 2 }; + /* * This struct is meant to be a thin wrapper around aie-rt, which provides * the canonical representation/metadata for AIE devices; attributes like number @@ -311,6 +303,7 @@ struct AMDAIEDeviceModel { uint32_t getNumDestSwitchboxConnections(int col, int row, StrmSwPortType bundle) const; uint32_t getNumMemTileRows() const { return 1; } + AIEArch getTargetArch() const { return AIEArch::AIE2; } }; struct AMDAIEDeviceModel getDeviceModel(AMDAIEDevice device); @@ -325,7 +318,6 @@ bool isNPUDevice(mlir::iree_compiler::AMDAIE::AMDAIEDevice d); _(int) \ _(uint32_t) \ _(uint64_t) \ - _(size_t) \ _(AMDAIEDmaProp) \ _(AMDAIETileType) \ _(AieRC) \ diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_12_i8_using_2d_dma_op_with_padding.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_12_i8_using_2d_dma_op_with_padding.mlir index a074fc581..d901ffd92 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_12_i8_using_2d_dma_op_with_padding.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_12_i8_using_2d_dma_op_with_padding.mlir @@ -4,8 +4,8 @@ module { aie.device(npu1_1col) { %tile_0_1 = aie.tile(0, 1) %objFifo_in0_cons_buff_0 = aie.buffer(%tile_0_1) {address = 0 : i32, sym_name = "objFifo_in0_cons_buff_0"} : memref<64x64xi8> - %objFifo_in0_cons_prod_lock = aie.lock(%tile_0_1, 0) {init = 1 : i32, sym_name = "objFifo_in0_cons_prod_lock"} - %objFifo_in0_cons_cons_lock = aie.lock(%tile_0_1, 1) {init = 0 : i32, sym_name = "objFifo_in0_cons_cons_lock"} + %objFifo_in0_cons_prod_lock = aie.lock(%tile_0_1, 0) {init = 1 : i8, sym_name = "objFifo_in0_cons_prod_lock"} + %objFifo_in0_cons_cons_lock = aie.lock(%tile_0_1, 1) {init = 0 : i8, sym_name = "objFifo_in0_cons_cons_lock"} %memtile_dma_0_1 = aie.memtile_dma(%tile_0_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb2, repeat_count = 1) ^bb1: // 2 preds: ^bb0, ^bb1 diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_21_i8_using_dma_op_with_padding.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_21_i8_using_dma_op_with_padding.mlir index d307ac0ca..124032d72 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_21_i8_using_dma_op_with_padding.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_21_i8_using_dma_op_with_padding.mlir @@ -5,8 +5,8 @@ module { %tile_0_1 = aie.tile(0, 1) %objFifo_in0_cons_buff_0 = aie.buffer(%tile_0_1) {address = 0 : i32, sym_name = "objFifo_in0_cons_buff_0"} : memref<16xi8> %objFifo_in0_cons_buff_1 = aie.buffer(%tile_0_1) {address = 16 : i32, sym_name = "objFifo_in0_cons_buff_1"} : memref<16xi8> - %objFifo_in0_cons_prod_lock = aie.lock(%tile_0_1, 0) {init = 2 : i32, sym_name = "objFifo_in0_cons_prod_lock"} - %objFifo_in0_cons_cons_lock = aie.lock(%tile_0_1, 1) {init = 0 : i32, sym_name = "objFifo_in0_cons_cons_lock"} + %objFifo_in0_cons_prod_lock = aie.lock(%tile_0_1, 0) {init = 2 : i8, sym_name = "objFifo_in0_cons_prod_lock"} + %objFifo_in0_cons_cons_lock = aie.lock(%tile_0_1, 1) {init = 0 : i8, sym_name = "objFifo_in0_cons_cons_lock"} %memtile_dma_0_1 = aie.memtile_dma(%tile_0_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) ^bb1: // pred: ^bb0 diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_378_i32_using_dma_op_with_padding.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_378_i32_using_dma_op_with_padding.mlir index 6bfe6cba7..970cc441a 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_378_i32_using_dma_op_with_padding.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/add_378_i32_using_dma_op_with_padding.mlir @@ -5,8 +5,8 @@ module { %tile_0_1 = aie.tile(0, 1) %objFifo_in0_cons_buff_0 = aie.buffer(%tile_0_1) {address = 0 : i32, sym_name = "objFifo_in0_cons_buff_0"} : memref<16xi32> %objFifo_in0_cons_buff_1 = aie.buffer(%tile_0_1) {address = 64 : i32, sym_name = "objFifo_in0_cons_buff_1"} : memref<16xi32> - %objFifo_in0_cons_prod_lock = aie.lock(%tile_0_1, 0) {init = 2 : i32, sym_name = "objFifo_in0_cons_prod_lock"} - %objFifo_in0_cons_cons_lock = aie.lock(%tile_0_1, 1) {init = 0 : i32, sym_name = "objFifo_in0_cons_cons_lock"} + %objFifo_in0_cons_prod_lock = aie.lock(%tile_0_1, 0) {init = 2 : i8, sym_name = "objFifo_in0_cons_prod_lock"} + %objFifo_in0_cons_cons_lock = aie.lock(%tile_0_1, 1) {init = 0 : i8, sym_name = "objFifo_in0_cons_cons_lock"} %memtile_dma_0_1 = aie.memtile_dma(%tile_0_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) ^bb1: // pred: ^bb0 diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x16_8xi32__dispatch_0_matmul_16x1_0.aiecc.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x16_8xi32__dispatch_0_matmul_16x1_0.aiecc.mlir index d50db45e3..2c25fb39e 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x16_8xi32__dispatch_0_matmul_16x1_0.aiecc.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x16_8xi32__dispatch_0_matmul_16x1_0.aiecc.mlir @@ -7,18 +7,18 @@ aie.device(npu1_4col) { %tile_1_1 = aie.tile(1, 1) %tile_2_1 = aie.tile(2, 1) %tile_0_2 = aie.tile(0, 2) - %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i32} - %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i32} - %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i32} - %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i32} - %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i32} - %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i32} - %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i32} - %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i32} - %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i32} - %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i32} - %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i32} - %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i32} + %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i8} + %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i8} + %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i8} + %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i8} + %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i8} + %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i8} + %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i8} + %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i8} + %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i8} + %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i8} + %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i8} + %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i8} %buf5 = aie.buffer(%tile_0_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf5"} : memref<16x8xi32> %buf4 = aie.buffer(%tile_1_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf4"} : memref<8x16xi32> %buf3 = aie.buffer(%tile_2_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf3"} : memref<16x16xi32> @@ -50,49 +50,49 @@ aie.device(npu1_4col) { aie.next_bd ^bb6 } %switchbox_0_0 = aie.switchbox(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_0_0 = aie.shim_mux(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_1_0 = aie.tile(1, 0) %switchbox_1_0 = aie.switchbox(%tile_1_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_0 = aie.tile(2, 0) %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %tile_1_2 = aie.tile(1, 2) %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_2 = aie.tile(2, 2) %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect + aie.connect } %memtile_dma_2_1 = aie.memtile_dma(%tile_2_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x64_32xi8__dispatch_0_matmul_tran_0.aiecc.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x64_32xi8__dispatch_0_matmul_tran_0.aiecc.mlir index 2e45df56c..38a4189e6 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x64_32xi8__dispatch_0_matmul_tran_0.aiecc.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_16x64_32xi8__dispatch_0_matmul_tran_0.aiecc.mlir @@ -7,18 +7,18 @@ aie.device(npu1_4col) { %tile_1_1 = aie.tile(1, 1) %tile_2_1 = aie.tile(2, 1) %tile_0_2 = aie.tile(0, 2) - %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i32} - %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i32} - %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i32} - %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i32} - %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i32} - %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i32} - %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i32} - %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i32} - %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i32} - %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i32} - %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i32} - %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i32} + %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i8} + %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i8} + %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i8} + %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i8} + %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i8} + %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i8} + %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i8} + %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i8} + %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i8} + %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i8} + %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i8} + %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i8} %buf5 = aie.buffer(%tile_0_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf5"} : memref<16x64xi8> %buf4 = aie.buffer(%tile_1_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf4"} : memref<32x64xi8> %buf3 = aie.buffer(%tile_2_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf3"} : memref<16x32xi32> @@ -50,49 +50,49 @@ aie.device(npu1_4col) { aie.next_bd ^bb6 } %switchbox_0_0 = aie.switchbox(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_0_0 = aie.shim_mux(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_1_0 = aie.tile(1, 0) %switchbox_1_0 = aie.switchbox(%tile_1_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_0 = aie.tile(2, 0) %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %tile_1_2 = aie.tile(1, 2) %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_2 = aie.tile(2, 2) %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect + aie.connect } %memtile_dma_2_1 = aie.memtile_dma(%tile_2_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_512x512_512xi32__dispatch_0_matmul__0.aiecc.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_512x512_512xi32__dispatch_0_matmul__0.aiecc.mlir index 1a69613f0..099b66f48 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_512x512_512xi32__dispatch_0_matmul__0.aiecc.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_512x512_512xi32__dispatch_0_matmul__0.aiecc.mlir @@ -26,142 +26,142 @@ aie.device(npu1_4col) { %tile_1_5 = aie.tile(1, 5) %tile_2_5 = aie.tile(2, 5) %tile_3_5 = aie.tile(3, 5) - %lock_3_1 = aie.lock(%tile_3_1, 9) {init = 4 : i32} - %lock_3_1_0 = aie.lock(%tile_3_1, 8) {init = 0 : i32} - %lock_3_1_1 = aie.lock(%tile_3_1, 7) {init = 1 : i32} - %lock_3_1_2 = aie.lock(%tile_3_1, 6) {init = 0 : i32} - %lock_3_1_3 = aie.lock(%tile_3_1, 5) {init = 1 : i32} - %lock_3_1_4 = aie.lock(%tile_3_1, 4) {init = 0 : i32} - %lock_3_1_5 = aie.lock(%tile_3_1, 3) {init = 1 : i32} - %lock_3_1_6 = aie.lock(%tile_3_1, 2) {init = 0 : i32} - %lock_3_1_7 = aie.lock(%tile_3_1, 1) {init = 1 : i32} - %lock_3_1_8 = aie.lock(%tile_3_1, 0) {init = 0 : i32} - %lock_2_1 = aie.lock(%tile_2_1, 9) {init = 4 : i32} - %lock_2_1_9 = aie.lock(%tile_2_1, 8) {init = 0 : i32} - %lock_2_1_10 = aie.lock(%tile_2_1, 7) {init = 1 : i32} - %lock_2_1_11 = aie.lock(%tile_2_1, 6) {init = 0 : i32} - %lock_2_1_12 = aie.lock(%tile_2_1, 5) {init = 1 : i32} - %lock_2_1_13 = aie.lock(%tile_2_1, 4) {init = 0 : i32} - %lock_2_1_14 = aie.lock(%tile_2_1, 3) {init = 1 : i32} - %lock_2_1_15 = aie.lock(%tile_2_1, 2) {init = 0 : i32} - %lock_2_1_16 = aie.lock(%tile_2_1, 1) {init = 1 : i32} - %lock_2_1_17 = aie.lock(%tile_2_1, 0) {init = 0 : i32} - %lock_1_1 = aie.lock(%tile_1_1, 9) {init = 4 : i32} - %lock_1_1_18 = aie.lock(%tile_1_1, 8) {init = 0 : i32} - %lock_1_1_19 = aie.lock(%tile_1_1, 7) {init = 1 : i32} - %lock_1_1_20 = aie.lock(%tile_1_1, 6) {init = 0 : i32} - %lock_1_1_21 = aie.lock(%tile_1_1, 5) {init = 1 : i32} - %lock_1_1_22 = aie.lock(%tile_1_1, 4) {init = 0 : i32} - %lock_1_1_23 = aie.lock(%tile_1_1, 3) {init = 1 : i32} - %lock_1_1_24 = aie.lock(%tile_1_1, 2) {init = 0 : i32} - %lock_1_1_25 = aie.lock(%tile_1_1, 1) {init = 1 : i32} - %lock_1_1_26 = aie.lock(%tile_1_1, 0) {init = 0 : i32} - %lock_0_1 = aie.lock(%tile_0_1, 9) {init = 4 : i32} - %lock_0_1_27 = aie.lock(%tile_0_1, 8) {init = 0 : i32} - %lock_0_1_28 = aie.lock(%tile_0_1, 7) {init = 1 : i32} - %lock_0_1_29 = aie.lock(%tile_0_1, 6) {init = 0 : i32} - %lock_0_1_30 = aie.lock(%tile_0_1, 5) {init = 1 : i32} - %lock_0_1_31 = aie.lock(%tile_0_1, 4) {init = 0 : i32} - %lock_0_1_32 = aie.lock(%tile_0_1, 3) {init = 1 : i32} - %lock_0_1_33 = aie.lock(%tile_0_1, 2) {init = 0 : i32} - %lock_0_1_34 = aie.lock(%tile_0_1, 1) {init = 1 : i32} - %lock_0_1_35 = aie.lock(%tile_0_1, 0) {init = 0 : i32} - %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 2 : i32} - %lock_0_2_36 = aie.lock(%tile_0_2, 4) {init = 0 : i32} - %lock_0_2_37 = aie.lock(%tile_0_2, 3) {init = 2 : i32} - %lock_0_2_38 = aie.lock(%tile_0_2, 2) {init = 0 : i32} - %lock_0_2_39 = aie.lock(%tile_0_2, 1) {init = 1 : i32} - %lock_0_2_40 = aie.lock(%tile_0_2, 0) {init = 0 : i32} - %lock_1_2 = aie.lock(%tile_1_2, 5) {init = 2 : i32} - %lock_1_2_41 = aie.lock(%tile_1_2, 4) {init = 0 : i32} - %lock_1_2_42 = aie.lock(%tile_1_2, 3) {init = 2 : i32} - %lock_1_2_43 = aie.lock(%tile_1_2, 2) {init = 0 : i32} - %lock_1_2_44 = aie.lock(%tile_1_2, 1) {init = 1 : i32} - %lock_1_2_45 = aie.lock(%tile_1_2, 0) {init = 0 : i32} - %lock_2_2 = aie.lock(%tile_2_2, 5) {init = 2 : i32} - %lock_2_2_46 = aie.lock(%tile_2_2, 4) {init = 0 : i32} - %lock_2_2_47 = aie.lock(%tile_2_2, 3) {init = 2 : i32} - %lock_2_2_48 = aie.lock(%tile_2_2, 2) {init = 0 : i32} - %lock_2_2_49 = aie.lock(%tile_2_2, 1) {init = 1 : i32} - %lock_2_2_50 = aie.lock(%tile_2_2, 0) {init = 0 : i32} - %lock_3_2 = aie.lock(%tile_3_2, 5) {init = 2 : i32} - %lock_3_2_51 = aie.lock(%tile_3_2, 4) {init = 0 : i32} - %lock_3_2_52 = aie.lock(%tile_3_2, 3) {init = 2 : i32} - %lock_3_2_53 = aie.lock(%tile_3_2, 2) {init = 0 : i32} - %lock_3_2_54 = aie.lock(%tile_3_2, 1) {init = 1 : i32} - %lock_3_2_55 = aie.lock(%tile_3_2, 0) {init = 0 : i32} - %lock_0_3 = aie.lock(%tile_0_3, 5) {init = 2 : i32} - %lock_0_3_56 = aie.lock(%tile_0_3, 4) {init = 0 : i32} - %lock_0_3_57 = aie.lock(%tile_0_3, 3) {init = 2 : i32} - %lock_0_3_58 = aie.lock(%tile_0_3, 2) {init = 0 : i32} - %lock_0_3_59 = aie.lock(%tile_0_3, 1) {init = 1 : i32} - %lock_0_3_60 = aie.lock(%tile_0_3, 0) {init = 0 : i32} - %lock_1_3 = aie.lock(%tile_1_3, 5) {init = 2 : i32} - %lock_1_3_61 = aie.lock(%tile_1_3, 4) {init = 0 : i32} - %lock_1_3_62 = aie.lock(%tile_1_3, 3) {init = 2 : i32} - %lock_1_3_63 = aie.lock(%tile_1_3, 2) {init = 0 : i32} - %lock_1_3_64 = aie.lock(%tile_1_3, 1) {init = 1 : i32} - %lock_1_3_65 = aie.lock(%tile_1_3, 0) {init = 0 : i32} - %lock_2_3 = aie.lock(%tile_2_3, 5) {init = 2 : i32} - %lock_2_3_66 = aie.lock(%tile_2_3, 4) {init = 0 : i32} - %lock_2_3_67 = aie.lock(%tile_2_3, 3) {init = 2 : i32} - %lock_2_3_68 = aie.lock(%tile_2_3, 2) {init = 0 : i32} - %lock_2_3_69 = aie.lock(%tile_2_3, 1) {init = 1 : i32} - %lock_2_3_70 = aie.lock(%tile_2_3, 0) {init = 0 : i32} - %lock_3_3 = aie.lock(%tile_3_3, 5) {init = 2 : i32} - %lock_3_3_71 = aie.lock(%tile_3_3, 4) {init = 0 : i32} - %lock_3_3_72 = aie.lock(%tile_3_3, 3) {init = 2 : i32} - %lock_3_3_73 = aie.lock(%tile_3_3, 2) {init = 0 : i32} - %lock_3_3_74 = aie.lock(%tile_3_3, 1) {init = 1 : i32} - %lock_3_3_75 = aie.lock(%tile_3_3, 0) {init = 0 : i32} - %lock_0_4 = aie.lock(%tile_0_4, 5) {init = 2 : i32} - %lock_0_4_76 = aie.lock(%tile_0_4, 4) {init = 0 : i32} - %lock_0_4_77 = aie.lock(%tile_0_4, 3) {init = 2 : i32} - %lock_0_4_78 = aie.lock(%tile_0_4, 2) {init = 0 : i32} - %lock_0_4_79 = aie.lock(%tile_0_4, 1) {init = 1 : i32} - %lock_0_4_80 = aie.lock(%tile_0_4, 0) {init = 0 : i32} - %lock_1_4 = aie.lock(%tile_1_4, 5) {init = 2 : i32} - %lock_1_4_81 = aie.lock(%tile_1_4, 4) {init = 0 : i32} - %lock_1_4_82 = aie.lock(%tile_1_4, 3) {init = 2 : i32} - %lock_1_4_83 = aie.lock(%tile_1_4, 2) {init = 0 : i32} - %lock_1_4_84 = aie.lock(%tile_1_4, 1) {init = 1 : i32} - %lock_1_4_85 = aie.lock(%tile_1_4, 0) {init = 0 : i32} - %lock_2_4 = aie.lock(%tile_2_4, 5) {init = 2 : i32} - %lock_2_4_86 = aie.lock(%tile_2_4, 4) {init = 0 : i32} - %lock_2_4_87 = aie.lock(%tile_2_4, 3) {init = 2 : i32} - %lock_2_4_88 = aie.lock(%tile_2_4, 2) {init = 0 : i32} - %lock_2_4_89 = aie.lock(%tile_2_4, 1) {init = 1 : i32} - %lock_2_4_90 = aie.lock(%tile_2_4, 0) {init = 0 : i32} - %lock_3_4 = aie.lock(%tile_3_4, 5) {init = 2 : i32} - %lock_3_4_91 = aie.lock(%tile_3_4, 4) {init = 0 : i32} - %lock_3_4_92 = aie.lock(%tile_3_4, 3) {init = 2 : i32} - %lock_3_4_93 = aie.lock(%tile_3_4, 2) {init = 0 : i32} - %lock_3_4_94 = aie.lock(%tile_3_4, 1) {init = 1 : i32} - %lock_3_4_95 = aie.lock(%tile_3_4, 0) {init = 0 : i32} - %lock_0_5 = aie.lock(%tile_0_5, 5) {init = 2 : i32} - %lock_0_5_96 = aie.lock(%tile_0_5, 4) {init = 0 : i32} - %lock_0_5_97 = aie.lock(%tile_0_5, 3) {init = 2 : i32} - %lock_0_5_98 = aie.lock(%tile_0_5, 2) {init = 0 : i32} - %lock_0_5_99 = aie.lock(%tile_0_5, 1) {init = 1 : i32} - %lock_0_5_100 = aie.lock(%tile_0_5, 0) {init = 0 : i32} - %lock_1_5 = aie.lock(%tile_1_5, 5) {init = 2 : i32} - %lock_1_5_101 = aie.lock(%tile_1_5, 4) {init = 0 : i32} - %lock_1_5_102 = aie.lock(%tile_1_5, 3) {init = 2 : i32} - %lock_1_5_103 = aie.lock(%tile_1_5, 2) {init = 0 : i32} - %lock_1_5_104 = aie.lock(%tile_1_5, 1) {init = 1 : i32} - %lock_1_5_105 = aie.lock(%tile_1_5, 0) {init = 0 : i32} - %lock_2_5 = aie.lock(%tile_2_5, 5) {init = 2 : i32} - %lock_2_5_106 = aie.lock(%tile_2_5, 4) {init = 0 : i32} - %lock_2_5_107 = aie.lock(%tile_2_5, 3) {init = 2 : i32} - %lock_2_5_108 = aie.lock(%tile_2_5, 2) {init = 0 : i32} - %lock_2_5_109 = aie.lock(%tile_2_5, 1) {init = 1 : i32} - %lock_2_5_110 = aie.lock(%tile_2_5, 0) {init = 0 : i32} - %lock_3_5 = aie.lock(%tile_3_5, 5) {init = 2 : i32} - %lock_3_5_111 = aie.lock(%tile_3_5, 4) {init = 0 : i32} - %lock_3_5_112 = aie.lock(%tile_3_5, 3) {init = 2 : i32} - %lock_3_5_113 = aie.lock(%tile_3_5, 2) {init = 0 : i32} - %lock_3_5_114 = aie.lock(%tile_3_5, 1) {init = 1 : i32} - %lock_3_5_115 = aie.lock(%tile_3_5, 0) {init = 0 : i32} + %lock_3_1 = aie.lock(%tile_3_1, 9) {init = 4 : i8} + %lock_3_1_0 = aie.lock(%tile_3_1, 8) {init = 0 : i8} + %lock_3_1_1 = aie.lock(%tile_3_1, 7) {init = 1 : i8} + %lock_3_1_2 = aie.lock(%tile_3_1, 6) {init = 0 : i8} + %lock_3_1_3 = aie.lock(%tile_3_1, 5) {init = 1 : i8} + %lock_3_1_4 = aie.lock(%tile_3_1, 4) {init = 0 : i8} + %lock_3_1_5 = aie.lock(%tile_3_1, 3) {init = 1 : i8} + %lock_3_1_6 = aie.lock(%tile_3_1, 2) {init = 0 : i8} + %lock_3_1_7 = aie.lock(%tile_3_1, 1) {init = 1 : i8} + %lock_3_1_8 = aie.lock(%tile_3_1, 0) {init = 0 : i8} + %lock_2_1 = aie.lock(%tile_2_1, 9) {init = 4 : i8} + %lock_2_1_9 = aie.lock(%tile_2_1, 8) {init = 0 : i8} + %lock_2_1_10 = aie.lock(%tile_2_1, 7) {init = 1 : i8} + %lock_2_1_11 = aie.lock(%tile_2_1, 6) {init = 0 : i8} + %lock_2_1_12 = aie.lock(%tile_2_1, 5) {init = 1 : i8} + %lock_2_1_13 = aie.lock(%tile_2_1, 4) {init = 0 : i8} + %lock_2_1_14 = aie.lock(%tile_2_1, 3) {init = 1 : i8} + %lock_2_1_15 = aie.lock(%tile_2_1, 2) {init = 0 : i8} + %lock_2_1_16 = aie.lock(%tile_2_1, 1) {init = 1 : i8} + %lock_2_1_17 = aie.lock(%tile_2_1, 0) {init = 0 : i8} + %lock_1_1 = aie.lock(%tile_1_1, 9) {init = 4 : i8} + %lock_1_1_18 = aie.lock(%tile_1_1, 8) {init = 0 : i8} + %lock_1_1_19 = aie.lock(%tile_1_1, 7) {init = 1 : i8} + %lock_1_1_20 = aie.lock(%tile_1_1, 6) {init = 0 : i8} + %lock_1_1_21 = aie.lock(%tile_1_1, 5) {init = 1 : i8} + %lock_1_1_22 = aie.lock(%tile_1_1, 4) {init = 0 : i8} + %lock_1_1_23 = aie.lock(%tile_1_1, 3) {init = 1 : i8} + %lock_1_1_24 = aie.lock(%tile_1_1, 2) {init = 0 : i8} + %lock_1_1_25 = aie.lock(%tile_1_1, 1) {init = 1 : i8} + %lock_1_1_26 = aie.lock(%tile_1_1, 0) {init = 0 : i8} + %lock_0_1 = aie.lock(%tile_0_1, 9) {init = 4 : i8} + %lock_0_1_27 = aie.lock(%tile_0_1, 8) {init = 0 : i8} + %lock_0_1_28 = aie.lock(%tile_0_1, 7) {init = 1 : i8} + %lock_0_1_29 = aie.lock(%tile_0_1, 6) {init = 0 : i8} + %lock_0_1_30 = aie.lock(%tile_0_1, 5) {init = 1 : i8} + %lock_0_1_31 = aie.lock(%tile_0_1, 4) {init = 0 : i8} + %lock_0_1_32 = aie.lock(%tile_0_1, 3) {init = 1 : i8} + %lock_0_1_33 = aie.lock(%tile_0_1, 2) {init = 0 : i8} + %lock_0_1_34 = aie.lock(%tile_0_1, 1) {init = 1 : i8} + %lock_0_1_35 = aie.lock(%tile_0_1, 0) {init = 0 : i8} + %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 2 : i8} + %lock_0_2_36 = aie.lock(%tile_0_2, 4) {init = 0 : i8} + %lock_0_2_37 = aie.lock(%tile_0_2, 3) {init = 2 : i8} + %lock_0_2_38 = aie.lock(%tile_0_2, 2) {init = 0 : i8} + %lock_0_2_39 = aie.lock(%tile_0_2, 1) {init = 1 : i8} + %lock_0_2_40 = aie.lock(%tile_0_2, 0) {init = 0 : i8} + %lock_1_2 = aie.lock(%tile_1_2, 5) {init = 2 : i8} + %lock_1_2_41 = aie.lock(%tile_1_2, 4) {init = 0 : i8} + %lock_1_2_42 = aie.lock(%tile_1_2, 3) {init = 2 : i8} + %lock_1_2_43 = aie.lock(%tile_1_2, 2) {init = 0 : i8} + %lock_1_2_44 = aie.lock(%tile_1_2, 1) {init = 1 : i8} + %lock_1_2_45 = aie.lock(%tile_1_2, 0) {init = 0 : i8} + %lock_2_2 = aie.lock(%tile_2_2, 5) {init = 2 : i8} + %lock_2_2_46 = aie.lock(%tile_2_2, 4) {init = 0 : i8} + %lock_2_2_47 = aie.lock(%tile_2_2, 3) {init = 2 : i8} + %lock_2_2_48 = aie.lock(%tile_2_2, 2) {init = 0 : i8} + %lock_2_2_49 = aie.lock(%tile_2_2, 1) {init = 1 : i8} + %lock_2_2_50 = aie.lock(%tile_2_2, 0) {init = 0 : i8} + %lock_3_2 = aie.lock(%tile_3_2, 5) {init = 2 : i8} + %lock_3_2_51 = aie.lock(%tile_3_2, 4) {init = 0 : i8} + %lock_3_2_52 = aie.lock(%tile_3_2, 3) {init = 2 : i8} + %lock_3_2_53 = aie.lock(%tile_3_2, 2) {init = 0 : i8} + %lock_3_2_54 = aie.lock(%tile_3_2, 1) {init = 1 : i8} + %lock_3_2_55 = aie.lock(%tile_3_2, 0) {init = 0 : i8} + %lock_0_3 = aie.lock(%tile_0_3, 5) {init = 2 : i8} + %lock_0_3_56 = aie.lock(%tile_0_3, 4) {init = 0 : i8} + %lock_0_3_57 = aie.lock(%tile_0_3, 3) {init = 2 : i8} + %lock_0_3_58 = aie.lock(%tile_0_3, 2) {init = 0 : i8} + %lock_0_3_59 = aie.lock(%tile_0_3, 1) {init = 1 : i8} + %lock_0_3_60 = aie.lock(%tile_0_3, 0) {init = 0 : i8} + %lock_1_3 = aie.lock(%tile_1_3, 5) {init = 2 : i8} + %lock_1_3_61 = aie.lock(%tile_1_3, 4) {init = 0 : i8} + %lock_1_3_62 = aie.lock(%tile_1_3, 3) {init = 2 : i8} + %lock_1_3_63 = aie.lock(%tile_1_3, 2) {init = 0 : i8} + %lock_1_3_64 = aie.lock(%tile_1_3, 1) {init = 1 : i8} + %lock_1_3_65 = aie.lock(%tile_1_3, 0) {init = 0 : i8} + %lock_2_3 = aie.lock(%tile_2_3, 5) {init = 2 : i8} + %lock_2_3_66 = aie.lock(%tile_2_3, 4) {init = 0 : i8} + %lock_2_3_67 = aie.lock(%tile_2_3, 3) {init = 2 : i8} + %lock_2_3_68 = aie.lock(%tile_2_3, 2) {init = 0 : i8} + %lock_2_3_69 = aie.lock(%tile_2_3, 1) {init = 1 : i8} + %lock_2_3_70 = aie.lock(%tile_2_3, 0) {init = 0 : i8} + %lock_3_3 = aie.lock(%tile_3_3, 5) {init = 2 : i8} + %lock_3_3_71 = aie.lock(%tile_3_3, 4) {init = 0 : i8} + %lock_3_3_72 = aie.lock(%tile_3_3, 3) {init = 2 : i8} + %lock_3_3_73 = aie.lock(%tile_3_3, 2) {init = 0 : i8} + %lock_3_3_74 = aie.lock(%tile_3_3, 1) {init = 1 : i8} + %lock_3_3_75 = aie.lock(%tile_3_3, 0) {init = 0 : i8} + %lock_0_4 = aie.lock(%tile_0_4, 5) {init = 2 : i8} + %lock_0_4_76 = aie.lock(%tile_0_4, 4) {init = 0 : i8} + %lock_0_4_77 = aie.lock(%tile_0_4, 3) {init = 2 : i8} + %lock_0_4_78 = aie.lock(%tile_0_4, 2) {init = 0 : i8} + %lock_0_4_79 = aie.lock(%tile_0_4, 1) {init = 1 : i8} + %lock_0_4_80 = aie.lock(%tile_0_4, 0) {init = 0 : i8} + %lock_1_4 = aie.lock(%tile_1_4, 5) {init = 2 : i8} + %lock_1_4_81 = aie.lock(%tile_1_4, 4) {init = 0 : i8} + %lock_1_4_82 = aie.lock(%tile_1_4, 3) {init = 2 : i8} + %lock_1_4_83 = aie.lock(%tile_1_4, 2) {init = 0 : i8} + %lock_1_4_84 = aie.lock(%tile_1_4, 1) {init = 1 : i8} + %lock_1_4_85 = aie.lock(%tile_1_4, 0) {init = 0 : i8} + %lock_2_4 = aie.lock(%tile_2_4, 5) {init = 2 : i8} + %lock_2_4_86 = aie.lock(%tile_2_4, 4) {init = 0 : i8} + %lock_2_4_87 = aie.lock(%tile_2_4, 3) {init = 2 : i8} + %lock_2_4_88 = aie.lock(%tile_2_4, 2) {init = 0 : i8} + %lock_2_4_89 = aie.lock(%tile_2_4, 1) {init = 1 : i8} + %lock_2_4_90 = aie.lock(%tile_2_4, 0) {init = 0 : i8} + %lock_3_4 = aie.lock(%tile_3_4, 5) {init = 2 : i8} + %lock_3_4_91 = aie.lock(%tile_3_4, 4) {init = 0 : i8} + %lock_3_4_92 = aie.lock(%tile_3_4, 3) {init = 2 : i8} + %lock_3_4_93 = aie.lock(%tile_3_4, 2) {init = 0 : i8} + %lock_3_4_94 = aie.lock(%tile_3_4, 1) {init = 1 : i8} + %lock_3_4_95 = aie.lock(%tile_3_4, 0) {init = 0 : i8} + %lock_0_5 = aie.lock(%tile_0_5, 5) {init = 2 : i8} + %lock_0_5_96 = aie.lock(%tile_0_5, 4) {init = 0 : i8} + %lock_0_5_97 = aie.lock(%tile_0_5, 3) {init = 2 : i8} + %lock_0_5_98 = aie.lock(%tile_0_5, 2) {init = 0 : i8} + %lock_0_5_99 = aie.lock(%tile_0_5, 1) {init = 1 : i8} + %lock_0_5_100 = aie.lock(%tile_0_5, 0) {init = 0 : i8} + %lock_1_5 = aie.lock(%tile_1_5, 5) {init = 2 : i8} + %lock_1_5_101 = aie.lock(%tile_1_5, 4) {init = 0 : i8} + %lock_1_5_102 = aie.lock(%tile_1_5, 3) {init = 2 : i8} + %lock_1_5_103 = aie.lock(%tile_1_5, 2) {init = 0 : i8} + %lock_1_5_104 = aie.lock(%tile_1_5, 1) {init = 1 : i8} + %lock_1_5_105 = aie.lock(%tile_1_5, 0) {init = 0 : i8} + %lock_2_5 = aie.lock(%tile_2_5, 5) {init = 2 : i8} + %lock_2_5_106 = aie.lock(%tile_2_5, 4) {init = 0 : i8} + %lock_2_5_107 = aie.lock(%tile_2_5, 3) {init = 2 : i8} + %lock_2_5_108 = aie.lock(%tile_2_5, 2) {init = 0 : i8} + %lock_2_5_109 = aie.lock(%tile_2_5, 1) {init = 1 : i8} + %lock_2_5_110 = aie.lock(%tile_2_5, 0) {init = 0 : i8} + %lock_3_5 = aie.lock(%tile_3_5, 5) {init = 2 : i8} + %lock_3_5_111 = aie.lock(%tile_3_5, 4) {init = 0 : i8} + %lock_3_5_112 = aie.lock(%tile_3_5, 3) {init = 2 : i8} + %lock_3_5_113 = aie.lock(%tile_3_5, 2) {init = 0 : i8} + %lock_3_5_114 = aie.lock(%tile_3_5, 1) {init = 1 : i8} + %lock_3_5_115 = aie.lock(%tile_3_5, 0) {init = 0 : i8} %buf99 = aie.buffer(%tile_0_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf99"} : memref<32x256xi32> %buf98 = aie.buffer(%tile_1_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf98"} : memref<32x256xi32> %buf97 = aie.buffer(%tile_2_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf97"} : memref<32x256xi32> @@ -807,238 +807,238 @@ aie.device(npu1_4col) { aie.next_bd ^bb8 } %switchbox_0_0 = aie.switchbox(%tile_0_0) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_0_0 = aie.shim_mux(%tile_0_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_1_0 = aie.switchbox(%tile_1_0) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_1_0 = aie.shim_mux(%tile_1_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_3_0 = aie.switchbox(%tile_3_0) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_3_1 = aie.switchbox(%tile_3_1) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_2_0 = aie.shim_mux(%tile_2_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %shim_mux_3_0 = aie.shim_mux(%tile_3_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_3 = aie.switchbox(%tile_0_3) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_4 = aie.switchbox(%tile_0_4) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_5 = aie.switchbox(%tile_0_5) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_1_3 = aie.switchbox(%tile_1_3) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_1_4 = aie.switchbox(%tile_1_4) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_1_5 = aie.switchbox(%tile_1_5) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_2_3 = aie.switchbox(%tile_2_3) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_2_4 = aie.switchbox(%tile_2_4) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_2_5 = aie.switchbox(%tile_2_5) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_3_2 = aie.switchbox(%tile_3_2) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_3_3 = aie.switchbox(%tile_3_3) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_3_4 = aie.switchbox(%tile_3_4) { - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_3_5 = aie.switchbox(%tile_3_5) { - aie.connect - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect + aie.connect } %memtile_dma_0_1 = aie.memtile_dma(%tile_0_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb20, repeat_count = 1) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xbf16__dispatch_0_matmul_64_0.aiecc.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xbf16__dispatch_0_matmul_64_0.aiecc.mlir index f50c6cc58..a62b69848 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xbf16__dispatch_0_matmul_64_0.aiecc.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xbf16__dispatch_0_matmul_64_0.aiecc.mlir @@ -7,18 +7,18 @@ aie.device(npu1_4col) { %tile_1_1 = aie.tile(1, 1) %tile_2_1 = aie.tile(2, 1) %tile_0_2 = aie.tile(0, 2) - %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i32} - %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i32} - %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i32} - %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i32} - %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i32} - %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i32} - %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i32} - %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i32} - %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i32} - %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i32} - %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i32} - %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i32} + %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i8} + %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i8} + %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i8} + %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i8} + %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i8} + %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i8} + %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i8} + %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i8} + %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i8} + %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i8} + %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i8} + %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i8} %buf5 = aie.buffer(%tile_0_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf5"} : memref<64x64xbf16> %buf4 = aie.buffer(%tile_1_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf4"} : memref<64x64xbf16> %buf3 = aie.buffer(%tile_2_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf3"} : memref<64x64xf32> @@ -50,49 +50,49 @@ aie.device(npu1_4col) { aie.next_bd ^bb6 } %switchbox_0_0 = aie.switchbox(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_0_0 = aie.shim_mux(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_1_0 = aie.tile(1, 0) %switchbox_1_0 = aie.switchbox(%tile_1_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_0 = aie.tile(2, 0) %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %tile_1_2 = aie.tile(1, 2) %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_2 = aie.tile(2, 2) %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect + aie.connect } %memtile_dma_2_1 = aie.memtile_dma(%tile_2_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xi8__dispatch_0_matmul_64x6_0.aiecc.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xi8__dispatch_0_matmul_64x6_0.aiecc.mlir index 00f59c5c0..c1e980539 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xi8__dispatch_0_matmul_64x6_0.aiecc.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_64x64_64xi8__dispatch_0_matmul_64x6_0.aiecc.mlir @@ -7,18 +7,18 @@ aie.device(npu1_4col) { %tile_1_1 = aie.tile(1, 1) %tile_2_1 = aie.tile(2, 1) %tile_0_2 = aie.tile(0, 2) - %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i32} - %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i32} - %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i32} - %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i32} - %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i32} - %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i32} - %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i32} - %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i32} - %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i32} - %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i32} - %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i32} - %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i32} + %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i8} + %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i8} + %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i8} + %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i8} + %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i8} + %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i8} + %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i8} + %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i8} + %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i8} + %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i8} + %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i8} + %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i8} %buf5 = aie.buffer(%tile_0_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf5"} : memref<64x64xi8> %buf4 = aie.buffer(%tile_1_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf4"} : memref<64x64xi8> %buf3 = aie.buffer(%tile_2_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf3"} : memref<64x64xi32> @@ -50,49 +50,49 @@ aie.device(npu1_4col) { aie.next_bd ^bb6 } %switchbox_0_0 = aie.switchbox(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_0_0 = aie.shim_mux(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_1_0 = aie.tile(1, 0) %switchbox_1_0 = aie.switchbox(%tile_1_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_0 = aie.tile(2, 0) %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %tile_1_2 = aie.tile(1, 2) %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_2 = aie.tile(2, 2) %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect + aie.connect } %memtile_dma_2_1 = aie.memtile_dma(%tile_2_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_8x32_16xi32__dispatch_0_matmul_8x32_0.aiecc.mlir b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_8x32_16xi32__dispatch_0_matmul_8x32_0.aiecc.mlir index 355b41b6a..0f1fda51a 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_8x32_16xi32__dispatch_0_matmul_8x32_0.aiecc.mlir +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/matmul_8x32_16xi32__dispatch_0_matmul_8x32_0.aiecc.mlir @@ -7,18 +7,18 @@ aie.device(npu1_4col) { %tile_1_1 = aie.tile(1, 1) %tile_2_1 = aie.tile(2, 1) %tile_0_2 = aie.tile(0, 2) - %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i32} - %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i32} - %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i32} - %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i32} - %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i32} - %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i32} - %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i32} - %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i32} - %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i32} - %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i32} - %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i32} - %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i32} + %lock_1_1 = aie.lock(%tile_1_1, 1) {init = 1 : i8} + %lock_1_1_0 = aie.lock(%tile_1_1, 0) {init = 0 : i8} + %lock_0_1 = aie.lock(%tile_0_1, 1) {init = 1 : i8} + %lock_0_1_1 = aie.lock(%tile_0_1, 0) {init = 0 : i8} + %lock_2_1 = aie.lock(%tile_2_1, 1) {init = 1 : i8} + %lock_2_1_2 = aie.lock(%tile_2_1, 0) {init = 0 : i8} + %lock_0_2 = aie.lock(%tile_0_2, 5) {init = 1 : i8} + %lock_0_2_3 = aie.lock(%tile_0_2, 4) {init = 0 : i8} + %lock_0_2_4 = aie.lock(%tile_0_2, 3) {init = 1 : i8} + %lock_0_2_5 = aie.lock(%tile_0_2, 2) {init = 0 : i8} + %lock_0_2_6 = aie.lock(%tile_0_2, 1) {init = 1 : i8} + %lock_0_2_7 = aie.lock(%tile_0_2, 0) {init = 0 : i8} %buf5 = aie.buffer(%tile_0_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf5"} : memref<8x16xi32> %buf4 = aie.buffer(%tile_1_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf4"} : memref<16x32xi32> %buf3 = aie.buffer(%tile_2_1) {address = 0 : i32, mem_bank = 0 : i32, sym_name = "buf3"} : memref<8x32xi32> @@ -50,49 +50,49 @@ aie.device(npu1_4col) { aie.next_bd ^bb6 } %switchbox_0_0 = aie.switchbox(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %shim_mux_0_0 = aie.shim_mux(%tile_0_0) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %switchbox_0_1 = aie.switchbox(%tile_0_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_1_0 = aie.tile(1, 0) %switchbox_1_0 = aie.switchbox(%tile_1_0) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_1_1 = aie.switchbox(%tile_1_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_0 = aie.tile(2, 0) %switchbox_2_0 = aie.switchbox(%tile_2_0) { - aie.connect + aie.connect } %switchbox_2_1 = aie.switchbox(%tile_2_1) { - aie.connect - aie.connect + aie.connect + aie.connect } %switchbox_0_2 = aie.switchbox(%tile_0_2) { - aie.connect - aie.connect - aie.connect + aie.connect + aie.connect + aie.connect } %tile_1_2 = aie.tile(1, 2) %switchbox_1_2 = aie.switchbox(%tile_1_2) { - aie.connect - aie.connect + aie.connect + aie.connect } %tile_2_2 = aie.tile(2, 2) %switchbox_2_2 = aie.switchbox(%tile_2_2) { - aie.connect + aie.connect } %memtile_dma_2_1 = aie.memtile_dma(%tile_2_1) { %0 = aie.dma_start(S2MM, 0, ^bb1, ^bb3, repeat_count = 1) From 9aa42ab8dcec71fcf22c6fcc5296124f8b3742c4 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 7 Aug 2024 01:09:03 -0500 Subject: [PATCH 10/12] remove mlir-aie submodule --- .github/workflows/ci.yml | 1 + .gitmodules | 4 - build_tools/ci/build_test_cpp.sh | 1 + compiler/plugins/target/AMD-AIE/aie/AIE.td | 2 +- .../plugins/target/AMD-AIE/aie/AIEAttrs.td | 2 +- .../plugins/target/AMD-AIE/aie/AIEDialect.cpp | 257 +++++++++++++++- .../plugins/target/AMD-AIE/aie/AIEDialect.h | 276 ++---------------- .../plugins/target/AMD-AIE/aie/AIEEnums.h | 2 +- compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 35 +-- .../plugins/target/AMD-AIE/aie/AIETypes.td | 2 +- compiler/plugins/target/AMD-AIE/aie/AIEX.td | 30 +- .../target/AMD-AIE/aie/AMDAIEXToStandard.cpp | 1 - .../iree-amd-aie/Target/AMDAIETargetBCF.cpp | 7 +- .../Target/AMDAIETargetLdScript.cpp | 6 +- experimental/delegate/README.md | 2 - iree_compiler_plugin.cmake | 1 - iree_runtime_plugin.cmake | 1 - .../aie_runtime/test/CMakeLists.txt | 6 - .../aie_runtime/test/cdo/CMakeLists.txt | 5 - third_party/mlir-aie | 1 - 20 files changed, 309 insertions(+), 333 deletions(-) delete mode 160000 third_party/mlir-aie diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 546bb6b3a..26d5625c6 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -84,6 +84,7 @@ jobs: with: path: ${{ env.CACHE_DIR }} key: linux-build-test-cpp-asserts-manylinux-v2-${{ github.sha }} + test_linux: runs-on: amd7940hs needs: build_test_linux diff --git a/.gitmodules b/.gitmodules index 3d0b202f2..a4b6a7412 100644 --- a/.gitmodules +++ b/.gitmodules @@ -6,10 +6,6 @@ path = third_party/mlir-air url = https://github.com/nod-ai/mlir-air.git shallow = true -[submodule "third_party/mlir-aie"] - path = third_party/mlir-aie - url = https://github.com/nod-ai/mlir-aie.git - shallow = true [submodule "third_party/aie-rt"] path = third_party/aie-rt url = https://github.com/Xilinx/aie-rt.git diff --git a/build_tools/ci/build_test_cpp.sh b/build_tools/ci/build_test_cpp.sh index 753bcd3cf..d462da28d 100644 --- a/build_tools/ci/build_test_cpp.sh +++ b/build_tools/ci/build_test_cpp.sh @@ -7,6 +7,7 @@ repo_root="$(cd $this_dir/../.. && pwd)" iree_dir="$(cd $repo_root/../iree && pwd)" build_dir="$repo_root/iree-build" install_dir="$repo_root/iree-install" +rm -rf "$build_dir" "$install_dir" mkdir -p "$build_dir" build_dir="$(cd $build_dir && pwd)" cache_dir="${cache_dir:-}" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIE.td b/compiler/plugins/target/AMD-AIE/aie/AIE.td index 9b674418f..94f3c686f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIE.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIE.td @@ -16,4 +16,4 @@ def AIE_Dialect : Dialect { let useDefaultAttributePrinterParser = 1; } -#endif // AIE_BASE \ No newline at end of file +#endif // AIE_BASE diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td index ebcfcad18..9d309dbdf 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEAttrs.td @@ -82,4 +82,4 @@ def BDPadLayoutArrayAttr : ArrayOfAttr< /*eltName*/BDPadLayoutAttr.cppClassName >; -#endif // AIE_ATTRS \ No newline at end of file +#endif // AIE_ATTRS diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index 1d5cea379..89beea625 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -19,6 +19,15 @@ using namespace xilinx::AIE; #include "aie/AIEDialect.cpp.inc" namespace xilinx::AIE { +std::optional symbolizeAIEDevice( + uint32_t d) { + return mlir::iree_compiler::AMDAIE::symbolizeAMDAIEDevice(d); +} + +std::optional symbolizeAIEDevice( + llvm::StringRef d) { + return mlir::iree_compiler::AMDAIE::symbolizeAMDAIEDevice(d); +} namespace detail { struct AIEObjectFifoTypeStorage : TypeStorage { @@ -41,7 +50,6 @@ AIEObjectFifoType AIEObjectFifoType::get(MemRefType elementType) { } mlir::MemRefType AIEObjectFifoType::getElementType() { - // 'getImpl' returns a pointer to the internal storage instance. return getImpl()->elementType; } @@ -78,7 +86,6 @@ static OptionalParseResult aieTypeParser(DialectAsmParser &parser, parser.parseGreater()) return failure(); - // Check that the type is a MemRef type. if (!llvm::isa(elementType)) { parser.emitError(typeLoc, "element type for an objectFifo must be " @@ -92,14 +99,9 @@ static OptionalParseResult aieTypeParser(DialectAsmParser &parser, if (name == "objectfifosubview") { if (parser.parseLess()) return failure(); - - // Parse the element type of the struct. MemRefType elementType; - // Parse the current element type. SMLoc typeLoc = parser.getCurrentLocation(); if (parser.parseType(elementType)) return failure(); - - // Check that the type is a MemRefType. if (!llvm::isa(elementType)) { parser.emitError(typeLoc, "element type for a subview must be " @@ -107,13 +109,9 @@ static OptionalParseResult aieTypeParser(DialectAsmParser &parser, << elementType; return failure(); } - - // Parse: `>` if (parser.parseGreater()) return failure(); - return result = AIEObjectFifoSubviewType::get(elementType), success(); } - return {}; } @@ -122,7 +120,6 @@ static ParseResult parse(Type &result, StringRef name, if (OptionalParseResult parseResult = aieTypeParser(parser, name, result); parseResult.has_value()) return parseResult.value(); - parser.emitError(parser.getNameLoc(), "unknown AIE dialect type: \"") << name << "\""; return failure(); @@ -141,7 +138,6 @@ void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { printer << "objectfifo<"; printer << objectFifoType.getElementType(); printer << '>'; - } else if (llvm::isa(type)) { auto subviewType = llvm::cast(type); printer << "objectfifosubview<"; @@ -150,8 +146,8 @@ void AIEDialect::printType(Type type, DialectAsmPrinter &printer) const { } } -// without this, canonicalize/cse/etc will lift eg constants out of core ops -// causing eg lower-to-aie to fail to converge +/// without this, canonicalize/cse/etc will lift eg constants out of core ops +/// causing eg lower-to-aie to fail to converge struct AIEDialectFoldInterface : DialectFoldInterface { using DialectFoldInterface::DialectFoldInterface; @@ -186,3 +182,234 @@ void AIEDialect::initialize() { // Include implementations for custom attributes #define GET_ATTRDEF_CLASSES #include "aie/AIEAttrs.cpp.inc" + +namespace xilinx::AIE { + +mlir::ParseResult parseObjectFifoProducerTile( + mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, + BDDimLayoutArrayAttr &dimensions) { + std::vector emptyDims = {}; + if (parser.parseOperand(operand)) return mlir::failure(); + if (succeeded(parser.parseOptionalKeyword("toStream"))) { + if (parser.parseCustomAttributeWithFallback( + dimensions)) { + return mlir::failure(); + } + } else { + dimensions = BDDimLayoutArrayAttr::get(parser.getContext(), + llvm::ArrayRef(emptyDims)); + } + return mlir::success(); +} + +void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::Value operand, + BDDimLayoutArrayAttr dimensions) { + printer << operand; + if (!dimensions.empty()) { + printer << " toStream "; + printer.printStrippedAttrOrType(dimensions); + } +} + +mlir::ParseResult parseObjectFifoConsumerTiles( + mlir::OpAsmParser &parser, + llvm::SmallVectorImpl &tiles, + BDDimLayoutArrayArrayAttr &dimensions) { + std::vector tileDims = {}; + auto parseOneOperand = [&]() -> llvm::ParseResult { + if (parser.parseOperand(tiles.emplace_back(), true)) { + return mlir::failure(); + } + BDDimLayoutArrayAttr dimAttr = + BDDimLayoutArrayAttr::get(parser.getContext(), {}); + if (succeeded(parser.parseOptionalKeyword("fromStream"))) { + if (parser.parseCustomAttributeWithFallback( + dimAttr)) { + return mlir::failure(); + } + } + tileDims.emplace_back(dimAttr); + return mlir::success(); + }; + + if (parser.parseCommaSeparatedList(mlir::AsmParser::Delimiter::None, + parseOneOperand, " in operand list")) + return mlir::failure(); + + dimensions = BDDimLayoutArrayArrayAttr::get(parser.getContext(), tileDims); + return mlir::success(); +} + +void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::OperandRange tiles, + BDDimLayoutArrayArrayAttr dimsPerTileAttr) { + size_t tileIdx = 0; + for (auto tile : tiles) { + printer << tile; + if (dimsPerTileAttr && tileIdx < dimsPerTileAttr.size() && + dimsPerTileAttr[tileIdx] && !dimsPerTileAttr[tileIdx].empty()) { + printer << " fromStream "; + printer.printStrippedAttrOrType(dimsPerTileAttr[tileIdx]); + } + if (tileIdx < tiles.size() - 1) { + printer << ", "; + } + tileIdx++; + } +} + +TileOp getTileOp(mlir::Operation &op) { + mlir::Value t = *op.getOperands().begin(); + return llvm::cast(t.getDefiningOp()); +} + +TileOp CoreOp::getTileOp() { return ::xilinx::AIE::getTileOp(*getOperation()); } + +TileOp BufferOp::getTileOp() { + return ::xilinx::AIE::getTileOp(*getOperation()); +} + +TileOp ShimDMAOp::getTileOp() { + return ::xilinx::AIE::getTileOp(*getOperation()); +} + +int32_t getBufferElementTypeWidthInBytes(DMABDOp &op) { + return op.getBuffer().getType().getElementTypeBitWidth() / 8; +} + +int32_t getLenInBytes(DMABDOp &op) { + if (std::optional len = op.getLen(); len.has_value()) + return len.value() * getBufferElementTypeWidthInBytes(op); + else + return op.getBuffer().getType().getNumElements() * + getBufferElementTypeWidthInBytes(op); +} + +int32_t getOffsetInBytes(DMABDOp &op) { + return op.getOffset() * getBufferElementTypeWidthInBytes(op); +} + +MemOp getMemOp(TileOp &op) { + auto users = op.getResult().getUsers(); + for (auto user : users) + if (auto memOp = llvm::dyn_cast(*user)) return memOp; + return nullptr; +} + +CoreOp getCoreOp(TileOp &op) { + auto users = op.getResult().getUsers(); + for (auto user : users) + if (auto coreOp = llvm::dyn_cast(*user)) return coreOp; + return nullptr; +} + +MemOp TileOp::getMemOp() { return ::xilinx::AIE::getMemOp(*this); } + +CoreOp TileOp::getCoreOp() { return ::xilinx::AIE::getCoreOp(*this); } + +void collectBuffers(DeviceOp &device, + llvm::DenseMap> &buffers) { + for (BufferOp buffer : device.getOps()) { + mlir::Operation *tileOp = buffer.getTile().getDefiningOp(); + buffers[tileOp].push_back(buffer); + } +} + +void collectTiles(xilinx::AIE::DeviceOp &device, + llvm::DenseMap &tiles) { + for (auto tile : device.getOps()) { + int getCol = tile.getCol(); + int getRow = tile.getRow(); + tiles[{getCol, getRow}] = tile; + } +} + +int64_t getAllocationSize(BufferOp &op) { + auto type = llvm::cast(op.getType()); + return type.getNumElements() * type.getElementTypeBitWidth() / 8; +} + +mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( + mlir::Operation *op) { + if (auto t = llvm::dyn_cast(op)) { + return mlir::iree_compiler::AMDAIE::getDeviceModel( + static_cast(t.getDevice())); + } + if (auto t = op->getParentOfType()) { + return mlir::iree_compiler::AMDAIE::getDeviceModel( + static_cast(t.getDevice())); + } + llvm::report_fatal_error("couldn't find device model for op"); +} + +size_t TileOp::getNumDestConnections( + mlir::iree_compiler::AMDAIE::StrmSwPortType s) { + auto deviceModel = getDeviceModel(this->getOperation()); + return deviceModel.getNumDestSwitchBoxConnections(this->getCol(), + this->getRow(), s); +} + +size_t TileOp::getNumSourceConnections( + mlir::iree_compiler::AMDAIE::StrmSwPortType s) { + auto deviceModel = getDeviceModel(this->getOperation()); + return deviceModel.getNumSourceSwitchBoxConnections(this->getCol(), + this->getRow(), s); +} + +bool TileOp::isMemTile() { + auto deviceModel = getDeviceModel(this->getOperation()); + return deviceModel.isMemTile(this->getCol(), this->getRow()); +} + +void SwitchboxOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void ShimMuxOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void MemOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void CoreOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void MemTileDMAOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void BufferOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void LockOp::getAsmResultNames( + llvm::function_ref setNameFn) { + return xilinx::AIE::getAsmResultNames(this, setNameFn); +} + +void TileOp::getAsmResultNames( + llvm::function_ref setNameFn) { + std::string nameWithoutDialect = + getOperationName().str().substr(getOperationName().find('.') + 1); + setNameFn(getResult(), nameWithoutDialect + "_" + std::to_string(getCol()) + + "_" + std::to_string(getRow())); +} + +mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel DeviceOp::getTargetModel() { + return getDeviceModel(this->getOperation()); +} + +uint32_t getAddressGenGranularity() { return 32; }; +} // namespace xilinx::AIE diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h index ec1caf38a..77588e7b9 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.h @@ -75,15 +75,10 @@ using AIEArch = mlir::iree_compiler::AMDAIE::AIEArch; using AIEDevice = mlir::iree_compiler::AMDAIE::AMDAIEDevice; using AIEDeviceAttr = mlir::iree_compiler::AMDAIE::AMDAIEDeviceAttr; -inline std::optional -symbolizeAIEDevice(uint32_t d) { - return mlir::iree_compiler::AMDAIE::symbolizeAMDAIEDevice(d); -} - -inline std::optional -symbolizeAIEDevice(llvm::StringRef d) { - return mlir::iree_compiler::AMDAIE::symbolizeAMDAIEDevice(d); -} +std::optional symbolizeAIEDevice( + uint32_t d); +std::optional symbolizeAIEDevice( + llvm::StringRef d); } // namespace xilinx::AIE #include "aie/AIEDialect.h.inc" @@ -96,200 +91,41 @@ symbolizeAIEDevice(llvm::StringRef d) { #include "aie/AIEOps.h.inc" namespace xilinx::AIE { - -inline mlir::ParseResult parseObjectFifoProducerTile( +mlir::ParseResult parseObjectFifoProducerTile( mlir::OpAsmParser &parser, mlir::OpAsmParser::UnresolvedOperand &operand, - BDDimLayoutArrayAttr &dimensions) { - std::vector emptyDims = {}; - if (parser.parseOperand(operand)) return mlir::failure(); - if (succeeded(parser.parseOptionalKeyword("toStream"))) { - if (parser.parseCustomAttributeWithFallback( - dimensions)) { - return mlir::failure(); - } - } else { - dimensions = BDDimLayoutArrayAttr::get(parser.getContext(), - llvm::ArrayRef(emptyDims)); - } - return mlir::success(); -} + BDDimLayoutArrayAttr &dimensions); -inline void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, - mlir::Operation *op, - mlir::Value operand, - BDDimLayoutArrayAttr dimensions) { - printer << operand; - if (!dimensions.empty()) { - printer << " toStream "; - printer.printStrippedAttrOrType(dimensions); - } -} +void printObjectFifoProducerTile(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::Value operand, + BDDimLayoutArrayAttr dimensions); -inline mlir::ParseResult parseObjectFifoConsumerTiles( +mlir::ParseResult parseObjectFifoConsumerTiles( mlir::OpAsmParser &parser, llvm::SmallVectorImpl &tiles, - BDDimLayoutArrayArrayAttr &dimensions) { - // parseCommaSeparatedList doesn't handle the missing case for "none", - // so we handle it custom here. - std::vector tileDims = {}; - - auto parseOneOperand = [&]() -> llvm::ParseResult { - if (parser.parseOperand(tiles.emplace_back(), true)) { - return mlir::failure(); - } - // 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 - BDDimLayoutArrayAttr dimAttr = - BDDimLayoutArrayAttr::get(parser.getContext(), {}); - - if (succeeded(parser.parseOptionalKeyword("fromStream"))) { - // If specified, parse actual data layout transform dimensions - if (parser.parseCustomAttributeWithFallback( - dimAttr)) { - return mlir::failure(); - } - } - tileDims.emplace_back(dimAttr); - return mlir::success(); - }; - - if (parser.parseCommaSeparatedList(mlir::AsmParser::Delimiter::None, - parseOneOperand, " in operand list")) - return mlir::failure(); - - dimensions = BDDimLayoutArrayArrayAttr::get(parser.getContext(), tileDims); - return mlir::success(); -} - -inline void printObjectFifoConsumerTiles( - mlir::OpAsmPrinter &printer, mlir::Operation *op, mlir::OperandRange tiles, - BDDimLayoutArrayArrayAttr dimsPerTileAttr) { - size_t tileIdx = 0; - for (auto tile : tiles) { - printer << tile; - if (dimsPerTileAttr && tileIdx < dimsPerTileAttr.size() && - dimsPerTileAttr[tileIdx] && !dimsPerTileAttr[tileIdx].empty()) { - printer << " fromStream "; - printer.printStrippedAttrOrType(dimsPerTileAttr[tileIdx]); - } - if (tileIdx < tiles.size() - 1) { - printer << ", "; - } - tileIdx++; - } -} - -inline TileOp getTileOp(mlir::Operation &op) { - mlir::Value t = *op.getOperands().begin(); - return llvm::cast(t.getDefiningOp()); -} - -inline TileOp CoreOp::getTileOp() { - return ::xilinx::AIE::getTileOp(*getOperation()); -} - -inline TileOp BufferOp::getTileOp() { - return ::xilinx::AIE::getTileOp(*getOperation()); -} - -inline TileOp ShimDMAOp::getTileOp() { - return ::xilinx::AIE::getTileOp(*getOperation()); -} - -inline int32_t getBufferElementTypeWidthInBytes(DMABDOp &op) { - return op.getBuffer().getType().getElementTypeBitWidth() / 8; -} - -inline int32_t getLenInBytes(DMABDOp &op) { - if (std::optional len = op.getLen(); len.has_value()) - return len.value() * getBufferElementTypeWidthInBytes(op); - else - return op.getBuffer().getType().getNumElements() * - getBufferElementTypeWidthInBytes(op); -} - -inline int32_t getOffsetInBytes(DMABDOp &op) { - return op.getOffset() * getBufferElementTypeWidthInBytes(op); -} - -inline MemOp getMemOp(TileOp &op) { - auto users = op.getResult().getUsers(); - for (auto user : users) - if (auto memOp = llvm::dyn_cast(*user)) return memOp; - return nullptr; -} - -inline CoreOp getCoreOp(TileOp &op) { - auto users = op.getResult().getUsers(); - for (auto user : users) - if (auto coreOp = llvm::dyn_cast(*user)) return coreOp; - return nullptr; -} - -inline MemOp TileOp::getMemOp() { return ::xilinx::AIE::getMemOp(*this); } - -inline CoreOp TileOp::getCoreOp() { return ::xilinx::AIE::getCoreOp(*this); } - -inline void collectBuffers( + BDDimLayoutArrayArrayAttr &dimensions); + +void printObjectFifoConsumerTiles(mlir::OpAsmPrinter &printer, + mlir::Operation *op, mlir::OperandRange tiles, + BDDimLayoutArrayArrayAttr dimsPerTileAttr); + +TileOp getTileOp(mlir::Operation &op); +int32_t getBufferElementTypeWidthInBytes(DMABDOp &op); +int32_t getLenInBytes(DMABDOp &op); +int32_t getOffsetInBytes(DMABDOp &op); +MemOp getMemOp(TileOp &op); +CoreOp getCoreOp(TileOp &op); +void collectBuffers( DeviceOp &device, - llvm::DenseMap> - &buffers) { - for (BufferOp buffer : device.getOps()) { - mlir::Operation *tileOp = buffer.getTile().getDefiningOp(); - buffers[tileOp].push_back(buffer); - } -} - -inline void collectTiles(xilinx::AIE::DeviceOp &device, - llvm::DenseMap &tiles) { - for (auto tile : device.getOps()) { - int getCol = tile.getCol(); - int getRow = tile.getRow(); - tiles[{getCol, getRow}] = tile; - } -} - -inline int64_t getAllocationSize(BufferOp &op) { - auto type = llvm::cast(op.getType()); - return type.getNumElements() * type.getElementTypeBitWidth() / 8; -} - -inline mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( - mlir::Operation *op) { - if (auto t = llvm::dyn_cast(op)) { - return mlir::iree_compiler::AMDAIE::getDeviceModel( - static_cast(t.getDevice())); - } - if (auto t = op->getParentOfType()) { - return mlir::iree_compiler::AMDAIE::getDeviceModel( - static_cast(t.getDevice())); - } - llvm::report_fatal_error("couldn't find device model for op"); -} - -inline size_t TileOp::getNumDestConnections( - mlir::iree_compiler::AMDAIE::StrmSwPortType s) { - auto deviceModel = getDeviceModel(this->getOperation()); - return deviceModel.getNumDestSwitchBoxConnections(this->getCol(), - this->getRow(), s); -} - -inline size_t TileOp::getNumSourceConnections( - mlir::iree_compiler::AMDAIE::StrmSwPortType s) { - auto deviceModel = getDeviceModel(this->getOperation()); - return deviceModel.getNumSourceSwitchBoxConnections(this->getCol(), - this->getRow(), s); -} - -inline bool TileOp::isMemTile() { - auto deviceModel = getDeviceModel(this->getOperation()); - return deviceModel.isMemTile(this->getCol(), this->getRow()); -} + llvm::DenseMap> &buffers); +void collectTiles(xilinx::AIE::DeviceOp &device, + llvm::DenseMap &tiles); +int64_t getAllocationSize(BufferOp &op); +mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel getDeviceModel( + mlir::Operation *op); template -inline void getAsmResultNames( +void getAsmResultNames( T op, llvm::function_ref setNameFn) { std::string nameWithoutDialect = op->getOperationName().str().substr(op->getOperationName().find('.') + 1); @@ -299,55 +135,7 @@ inline void getAsmResultNames( std::to_string(t.getRow())); } -inline void SwitchboxOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void ShimMuxOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void MemOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void CoreOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void MemTileDMAOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void BufferOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void LockOp::getAsmResultNames( - llvm::function_ref setNameFn) { - return xilinx::AIE::getAsmResultNames(this, setNameFn); -} - -inline void TileOp::getAsmResultNames( - llvm::function_ref setNameFn) { - std::string nameWithoutDialect = - getOperationName().str().substr(getOperationName().find('.') + 1); - setNameFn(getResult(), nameWithoutDialect + "_" + std::to_string(getCol()) + - "_" + std::to_string(getRow())); -} - -inline mlir::iree_compiler::AMDAIE::AMDAIEDeviceModel -DeviceOp::getTargetModel() { - return getDeviceModel(this->getOperation()); -} - -inline uint32_t getAddressGenGranularity() { return 32; }; +uint32_t getAddressGenGranularity(); struct DMAChannel { DMAChannelDir direction; diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h b/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h index 7e6dbe508..b1628d732 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h +++ b/compiler/plugins/target/AMD-AIE/aie/AIEEnums.h @@ -12,4 +12,4 @@ #include "aie/AIEEnums.h.inc" -#endif \ No newline at end of file +#endif diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index 3862babc3..edbb52407 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -22,7 +22,6 @@ include "mlir/IR/OpAsmInterface.td" class AIE_Op traits = []> : Op; - def AIE_DeviceOp: AIE_Op<"device", [ HasParent<"mlir::ModuleOp">, SymbolTable, SingleBlock, NoTerminator, IsolatedFromAbove @@ -146,7 +145,7 @@ def AIE_CoreOp: AIE_Op<"core", [ }]; } -def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { +def AIE_ConnectOp: AIE_Op<"connect"> { let arguments = ( ins StrmSwPortTypeAttr:$source_bundle, ConfinedAttr]>:$source_channel, @@ -159,7 +158,7 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> }]; } -def AIE_FlowOp: AIE_Op<"flow", []> { +def AIE_FlowOp: AIE_Op<"flow"> { let arguments = ( ins Index:$source, StrmSwPortTypeAttr:$source_bundle, @@ -222,7 +221,7 @@ def AIE_PacketRulesOp: AIE_Op<"packet_rules", [SingleBlockImplicitTerminator<"En let assemblyFormat = [{ `(` $source_bundle `:` $source_channel `)` regions attr-dict }]; } -def AIE_PacketRuleOp: AIE_Op<"rule", [HasParent<"PacketRulesOp">]> { +def AIE_PacketRuleOp: AIE_Op<"rule"> { let arguments = ( ins I8Attr:$mask, I8Attr:$value, @@ -250,7 +249,7 @@ def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndO }]; } -def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { +def AIE_PacketSourceOp: AIE_Op<"packet_source"> { let arguments = ( ins Index:$tile, StrmSwPortTypeAttr:$bundle, @@ -267,7 +266,7 @@ def AIE_PacketSourceOp: AIE_Op<"packet_source", [HasParent<"PacketFlowOp">]> { }]; } -def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { +def AIE_PacketDestOp: AIE_Op<"packet_dest"> { let arguments = ( ins Index:$tile, StrmSwPortTypeAttr:$bundle, @@ -284,7 +283,7 @@ def AIE_PacketDestOp: AIE_Op<"packet_dest", [HasParent<"PacketFlowOp">]> { }]; } -def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { +def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet"> { let summary = "Enable packet headers for a dma block descriptor"; let arguments = ( ins I32Attr:$packet_type, @@ -298,13 +297,12 @@ def AIE_DMABDPACKETOp: AIE_Op<"dma_bd_packet", []> { def AIE_DMABDOp: AIE_Op<"dma_bd", [ DeclareOpInterfaceMethods, - ParentOneOf<["MemOp", "MemTileDMAOp"]>, ]> { let summary = "Declare a dma buffer descriptor op"; let arguments = ( ins AnyMemRef:$buffer, // in multiples of element width (not bytes) - DefaultValuedOptionalAttr:$offset, + DefaultValuedOptionalAttr:$offset, // in multiples of element width (not bytes) OptionalAttr:$len, OptionalAttr:$dimensions, @@ -349,7 +347,6 @@ def AIE_DMABDOp: AIE_Op<"dma_bd", [ } def AIE_DMAStartOp: AIE_Op<"dma_start", [ - ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp"]>, Terminator, DeclareOpInterfaceMethods ]>, Results<(outs I1:$valid)> { @@ -399,9 +396,7 @@ def AIE_MemTileDMAOp: AIE_Op<"memtile_dma", [ }]; } -def AIE_NextBDOp: AIE_Op<"next_bd", [ - Terminator, ParentOneOf<["MemOp", "MemTileDMAOp", "mlir::func::FuncOp"]> - ]> { +def AIE_NextBDOp: AIE_Op<"next_bd", [Terminator]> { let summary = "The next buffer descriptor"; let successors = (successor AnySuccessor:$dest); @@ -446,7 +441,7 @@ def AIE_LockOp: AIE_Op<"lock", [ }]; } -def AIE_UseLockOp: AIE_Op<"use_lock", []> { +def AIE_UseLockOp: AIE_Op<"use_lock"> { let summary = "acquire/release lock op"; let arguments = ( ins Index:$lock, @@ -492,7 +487,7 @@ def AIE_BufferOp: AIE_Op<"buffer", [ }]; } -def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp">]> { +def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation"> { let summary = "Runtime allocation information for a single shim DMA"; let arguments = ( ins FlatSymbolRefAttr:$sym_name, @@ -510,7 +505,7 @@ def AIE_ShimDMAAllocationOp : AIE_Op<"shim_dma_allocation", [HasParent<"DeviceOp }]; } -def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol]> { +def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [Symbol]> { let summary = "Create a circular buffer or channel between two tiles"; let arguments = ( ins SymbolNameAttr:$sym_name, @@ -560,7 +555,7 @@ def AIE_ObjectFifoCreateOp: AIE_Op<"objectfifo", [HasParent<"DeviceOp">, Symbol] }]; } -def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { +def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link"> { let summary = "Links two objectFifos through an intermediary tile's DMA"; let arguments = ( ins SymbolRefArrayAttr:$fifoIns, @@ -574,7 +569,7 @@ def AIE_ObjectFifoLinkOp: AIE_Op<"objectfifo.link", [HasParent<"DeviceOp">]> { }]; } -def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { +def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire"> { let summary = "Acquire operation to lock and return objects of an ObjectFifo"; let arguments = ( ins ObjectFifoPort:$port, @@ -590,7 +585,7 @@ def AIE_ObjectFifoAcquireOp: AIE_Op<"objectfifo.acquire", []> { } -def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { +def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release"> { let summary = "Release operation for object locks in an ObjectFifo"; let arguments = ( ins ObjectFifoPort:$port, @@ -604,7 +599,7 @@ def AIE_ObjectFifoReleaseOp: AIE_Op<"objectfifo.release", []> { } -def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access", []> { +def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access"> { let summary = "ObjectFifoSubview type accessor method"; let arguments = ( ins AIE_ObjectFifoSubviewType:$subview, diff --git a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td index 33e68dde1..41a81d510 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIETypes.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIETypes.td @@ -20,4 +20,4 @@ def AIE_ObjectFifoSubviewType : DialectType($_self)">, "AIE ObjectFifoSubview type">; -#endif // AIE_TYPES \ No newline at end of file +#endif // AIE_TYPES diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEX.td b/compiler/plugins/target/AMD-AIE/aie/AIEX.td index 61d916424..69fd6bc59 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEX.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEX.td @@ -26,8 +26,7 @@ def AIEX_Dialect : Dialect { class AIEX_Op traits = []> : Op; - -def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator, HasParent<"AIE::DeviceOp">]> { +def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator]> { let summary = "Program the configuration co-processor of the AI Engine array"; let arguments = ( ins OptionalAttr:$sym_name @@ -82,7 +81,7 @@ def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [ }]; } -def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { +def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait"> { let summary = "Blocking operation to wait for a DMA to complete execution."; let arguments = ( ins FlatSymbolRefAttr:$symbol @@ -92,18 +91,7 @@ def AIE_NpuDmaWaitOp: AIEX_Op<"npu.dma_wait", []> { }]; } -def AIE_NpuWriteRTPOp: AIEX_Op<"npu.rtp_write", []> { - let summary = "rtp write operator"; - let arguments = ( - ins FlatSymbolRefAttr:$buffer, - UI32Attr:$index, - I32Attr:$value - ); - let results = (outs ); - let assemblyFormat = [{ `(` $buffer `,` $index `,` $value `)` attr-dict }]; -} - -def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue", []> { +def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue"> { let summary = "bd queue push operator"; let arguments = ( ins I32Attr:$column, @@ -120,7 +108,7 @@ def AIE_NpuPushQueueOp: AIEX_Op<"npu.push_queue", []> { }]; } -def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> { +def AIE_NpuWrite32Op: AIEX_Op<"npu.write32"> { let summary = "write32 operator"; let arguments = ( ins UI32Attr:$address, @@ -135,7 +123,7 @@ def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> { }]; } -def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite", []> { +def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite"> { let summary = "blockwrite operator"; let arguments = ( ins UI32Attr:$address, @@ -151,7 +139,7 @@ def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite", []> { } // OP_SYNC -def AIE_NpuSyncOp: AIEX_Op<"npu.sync", []> { +def AIE_NpuSyncOp: AIEX_Op<"npu.sync"> { let summary = "sync operator"; let arguments = ( ins I32Attr:$column, @@ -167,7 +155,7 @@ def AIE_NpuSyncOp: AIEX_Op<"npu.sync", []> { }]; } -def AIE_NpuAddressPatchOp: AIEX_Op<"npu.address_patch", []> { +def AIE_NpuAddressPatchOp: AIEX_Op<"npu.address_patch"> { let summary = "address patch operator"; let arguments = ( ins UI32Attr:$addr, @@ -181,7 +169,7 @@ def AIE_NpuAddressPatchOp: AIEX_Op<"npu.address_patch", []> { } // NPU Bd Write operation -def AIE_NpuWriteBdOp: AIEX_Op<"npu.writebd", []> { +def AIE_NpuWriteBdOp: AIEX_Op<"npu.writebd"> { let summary = "dma operator"; let arguments = ( ins I32Attr:$column, @@ -214,4 +202,4 @@ def AIE_NpuWriteBdOp: AIEX_Op<"npu.writebd", []> { let assemblyFormat = [{ attr-dict }]; } -#endif // AIEX_OPS \ No newline at end of file +#endif // AIEX_OPS diff --git a/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp b/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp index f9416d7bc..4e0de9c09 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AMDAIEXToStandard.cpp @@ -67,7 +67,6 @@ struct AMDAIEXToStandardPass : mlir::OperationPass { removepatterns.add>(m.getContext(), m); removepatterns.add>(m.getContext(), m); removepatterns.add>(m.getContext(), m); - removepatterns.add>(m.getContext(), m); removepatterns.add>(m.getContext(), m); removepatterns.add>(m.getContext(), m); removepatterns.add>(m.getContext(), m); diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp index 735502b15..48fc13527 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetBCF.cpp @@ -6,7 +6,6 @@ #include "AMDAIETargets.h" #include "aie/AIEDialect.h" -#include "aie/Passes.h" #include "llvm/ADT/StringExtras.h" #include "llvm/IR/Module.h" @@ -16,8 +15,6 @@ using namespace xilinx::AIE; std::string utohexstr(uint32_t u) { return "0x" + llvm::utohexstr(u); } -namespace {} // namespace - namespace mlir::iree_compiler::AMDAIE { LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, @@ -115,8 +112,8 @@ LogicalResult AIETranslateToBCF(ModuleOp module, raw_ostream &output, "the core can't see\n"; // chess's libc expects a _main not a main (despite what me_basic.c looks // like...) - output << "_resolve _main core_" << tile.getCol() << "_" << tile.getRow() - << "\n"; + output << "_resolve _main core_" << std::to_string(tile.getCol()) << "_" + << std::to_string(tile.getRow()) << "\n"; } return success(); diff --git a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp index d770e81df..a106f1e53 100644 --- a/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp +++ b/compiler/plugins/target/AMD-AIE/iree-amd-aie/Target/AMDAIETargetLdScript.cpp @@ -101,7 +101,7 @@ SECTIONS } > data )THESCRIPT"; auto doBuffer = [&](std::optional tile, int offset, - std::string dir) { + const std::string& dir) { if (tile) { if (tiles.count({tile->col, tile->row})) for (auto buf : buffers[tiles[{tile->col, tile->row}]]) @@ -139,8 +139,8 @@ SECTIONS output << " .bss.DMb.4 : { *(.bss.DMb.4) } > data\n"; output << "}\n"; if (auto coreOp = getCoreOp(tile)) { - output << "PROVIDE(main = core_" << tile.getCol() << "_" - << tile.getRow() << ");\n"; + output << "PROVIDE(main = core_" << std::to_string(tile.getCol()) << "_" + << std::to_string(tile.getRow()) << ");\n"; } } return success(); diff --git a/experimental/delegate/README.md b/experimental/delegate/README.md index 002ac7e88..6b15bb37f 100644 --- a/experimental/delegate/README.md +++ b/experimental/delegate/README.md @@ -211,12 +211,10 @@ cd export IREE_ROOT=$PWD cd iree-amd-aie/experimental/delegate export IREE_INSTALL_DIR=$IREE_ROOT/iree-build/ -export MLIR_AIE_INSTALL_DIR=$IREE_ROOT/iree-amd-aie/third_party/mlir-aie/install export PEANO_INSTALL_DIR=$IREE_ROOT/install export VITIS_INSTALL_PATH=/proj/xbuilds/2023.2_released/installs/lin64/Vitis/2023.2 ../../build_tools/ci/run_matmul_test.sh results_dir_tmp $IREE_INSTALL_DIR \ - $MLIR_AIE_INSTALL_DIR $PEANO_INSTALL_DIR /opt/xilinx/xrt \ $VITIS_INSTALL_PATH 0 ``` diff --git a/iree_compiler_plugin.cmake b/iree_compiler_plugin.cmake index 1061b273b..7ec4465b4 100644 --- a/iree_compiler_plugin.cmake +++ b/iree_compiler_plugin.cmake @@ -10,7 +10,6 @@ include_directories(${Boost_INCLUDE_DIRS}) set(IREE_AMD_AIE_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}") set(IREE_AMD_AIE_RUNTIME_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/runtime/src) set(IREE_MLIR_AIR_SOURCE_DIR "${IREE_AMD_AIE_SOURCE_DIR}/third_party/mlir-air/mlir") -set(IREE_MLIR_AIE_SOURCE_DIR "${IREE_AMD_AIE_SOURCE_DIR}/third_party/mlir-aie") add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/compiler/plugins/target/AMD-AIE target/AMD-AIE) add_subdirectory(${CMAKE_CURRENT_LIST_DIR}/tests/samples AMD-AIE/tests/samples) diff --git a/iree_runtime_plugin.cmake b/iree_runtime_plugin.cmake index 080c78bbe..b76099120 100644 --- a/iree_runtime_plugin.cmake +++ b/iree_runtime_plugin.cmake @@ -8,7 +8,6 @@ include(FetchContent) set(IREE_AMD_AIE_SOURCE_DIR "${CMAKE_CURRENT_LIST_DIR}") set(IREE_MLIR_AIR_SOURCE_DIR "${IREE_AMD_AIE_SOURCE_DIR}/third_party/mlir-air/mlir") -set(IREE_MLIR_AIE_SOURCE_DIR "${IREE_AMD_AIE_SOURCE_DIR}/third_party/mlir-aie") set(IREE_AMD_AIE_ENABLE_XRT_DRIVER OFF) if("xrt" IN_LIST IREE_EXTERNAL_HAL_DRIVERS) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt b/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt index 227bda174..6ec772dd6 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt +++ b/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt @@ -105,10 +105,4 @@ iree_lit_test( "hostonly" ) - -#target_include_directories( -# iree-amd-aie_aie_runtime_test_DeviceModelTestCppTest -# PRIVATE "${IREE_MLIR_AIE_SOURCE_DIR}/include" -#) - add_subdirectory(cdo) diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/CMakeLists.txt b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/CMakeLists.txt index b20e0518c..664c78da6 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/cdo/CMakeLists.txt +++ b/runtime/src/iree-amd-aie/aie_runtime/test/cdo/CMakeLists.txt @@ -14,11 +14,6 @@ iree_cc_binary( iree_target_amd-aie_Target_AIETargets ) -target_include_directories( - iree-amd-aie_aie_runtime_test_cdo_aie_cdo_gen_test - PRIVATE "${IREE_MLIR_AIE_SOURCE_DIR}/include" -) - file(GLOB _mlir_files *.mlir) iree_lit_test_suite( diff --git a/third_party/mlir-aie b/third_party/mlir-aie deleted file mode 160000 index 527370a0d..000000000 --- a/third_party/mlir-aie +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 527370a0d3982a20a8559944fbcaa532356b2819 From 0177da9ac32500710c8eff88af69813cd4d49350 Mon Sep 17 00:00:00 2001 From: max Date: Wed, 7 Aug 2024 16:18:53 -0500 Subject: [PATCH 11/12] remove devicemodel/targetmodel comparison test --- .../aie_runtime/test/CMakeLists.txt | 11 - .../aie_runtime/test/DeviceModelTest.cpp | 487 ------------------ 2 files changed, 498 deletions(-) delete mode 100644 runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt b/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt index 6ec772dd6..24f4383d4 100644 --- a/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt +++ b/runtime/src/iree-amd-aie/aie_runtime/test/CMakeLists.txt @@ -31,17 +31,6 @@ iree_lit_test( "hostonly" ) -#iree_cc_test( -# NAME -# DeviceModelTestCppTest -# SRCS -# DeviceModelTest.cpp -# DEPS -# gtest -# iree::target::amd-aie::aie::AIEDialectIR -# iree-amd-aie::aie_runtime::iree_aie_runtime_static -#) - iree_cc_test( NAME test_0335_aie_dma_tile_dma_packet_switch_mode diff --git a/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp b/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp deleted file mode 100644 index 91748e150..000000000 --- a/runtime/src/iree-amd-aie/aie_runtime/test/DeviceModelTest.cpp +++ /dev/null @@ -1,487 +0,0 @@ -// Copyright 2024 The IREE Authors -// -// 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 - -#include -#include - -extern "C" { -#include "xaiengine.h" -#include "xaiengine/xaie_ss_aieml.h" -#undef s8 -#undef u8 -#undef u16 -#undef s32 -#undef u32 -#undef u64 -} - -#include "aie/AIEDialect.h" -#include "aie/Dialect/AIE/IR/AIETargetModel.h" -#include "gtest/gtest-param-test.h" -#include "gtest/gtest.h" -#include "iree-amd-aie/aie_runtime/iree_aie_runtime.h" -#include "llvm/Support/FormatVariadic.h" - -// Without this using you do not get the operator<< overloads in -// iree_aie_runtime.h. -using namespace mlir::iree_compiler::AMDAIE; - -namespace { -using mlir::iree_compiler::AMDAIE::StrmSwPortType; -const std::map - _STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE = { - {StrmSwPortType::CORE, xilinx::AIE::WireBundle::Core}, - {StrmSwPortType::DMA, xilinx::AIE::WireBundle::DMA}, - {StrmSwPortType::CTRL, xilinx::AIE::WireBundle::Ctrl}, - {StrmSwPortType::FIFO, xilinx::AIE::WireBundle::FIFO}, - {StrmSwPortType::SOUTH, xilinx::AIE::WireBundle::South}, - {StrmSwPortType::WEST, xilinx::AIE::WireBundle::West}, - {StrmSwPortType::NORTH, xilinx::AIE::WireBundle::North}, - {StrmSwPortType::EAST, xilinx::AIE::WireBundle::East}, - {StrmSwPortType::TRACE, xilinx::AIE::WireBundle::Trace}, -}; - -xilinx::AIE::WireBundle STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE(StrmSwPortType s) { - return _STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE.at(s); -} - -template -class AMDAIENPUDeviceModelParameterizedTupleNPU4ColTestFixture - : public ::testing::TestWithParam> { - public: - explicit AMDAIENPUDeviceModelParameterizedTupleNPU4ColTestFixture() - : deviceModel(mlir::iree_compiler::AMDAIE::getDeviceModel(D)), - targetModel(xilinx::AIE::getTargetModel(T)) {} - - protected: - AMDAIEDeviceModel deviceModel; - const xilinx::AIE::AIETargetModel &targetModel; -}; - -template -class AMDAIENPUDeviceModelParameterizedTupleTestNPU4ColFixture - : public AMDAIENPUDeviceModelParameterizedTupleNPU4ColTestFixture< - AMDAIEDevice::npu1_4col, xilinx::AIE::AIEDevice::npu1_4col, - Types...> {}; - -class AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture - : public AMDAIENPUDeviceModelParameterizedTupleTestNPU4ColFixture {}; - -class - AMDAIENPUDeviceModelParameterizedAllPairsTimesAllSwitchesNPU4ColTestFixture - : public AMDAIENPUDeviceModelParameterizedTupleTestNPU4ColFixture {}; - -class AMDAIENPUDeviceModelParameterizedAllPairsTimesAllPairsNPU4ColTestFixture - : public AMDAIENPUDeviceModelParameterizedTupleTestNPU4ColFixture< - int, int, int, int> {}; - -class AMDAIENPUDeviceModelParameterizedSixTupleNPU4ColTestFixture - : public AMDAIENPUDeviceModelParameterizedTupleTestNPU4ColFixture< - int, int, StrmSwPortType, StrmSwPortType, int, int> {}; - -TEST(SameNumRowsCols_NPU1, Test0) { - AMDAIEDeviceModel deviceModel = - mlir::iree_compiler::AMDAIE::getDeviceModel(AMDAIEDevice::npu1); - const xilinx::AIE::AIETargetModel &targetModel = - xilinx::AIE::getTargetModel(xilinx::AIE::AIEDevice::npu1); - - EXPECT_EQ(deviceModel.rows(), targetModel.rows()); - EXPECT_EQ(deviceModel.columns(), targetModel.columns()); -} - -TEST(SameNumRowsCols_NPU1_4Col, Test0) { - AMDAIEDeviceModel deviceModel = - mlir::iree_compiler::AMDAIE::getDeviceModel(AMDAIEDevice::npu1_4col); - const xilinx::AIE::AIETargetModel &targetModel = - xilinx::AIE::getTargetModel(xilinx::AIE::AIEDevice::npu1_4col); - - // https://github.com/Xilinx/aie-rt/blob/38fcf1f9eb7c678defaf8c19ffb50a679b644452/driver/src/global/xaiegbl.c#L203 - // mlir-aie gets this wrong; the relationship is partitionStartCol + - // partitionNumCols < devNumCols - // mlir-aie sets devNumCols == partitionNumCols - EXPECT_EQ(deviceModel.rows(), targetModel.rows()); - EXPECT_NE(deviceModel.columns(), targetModel.columns()); -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - CoreTilesAgree) { - auto [c, r] = GetParam(); - mlir::iree_compiler::AMDAIE::AMDAIETileType tt = - deviceModel.getTileType(c, r); - EXPECT_EQ(deviceModel.isCoreTile(c, r), targetModel.isCoreTile(c, r)) - << "Core tile disagree; " << tt; - if (deviceModel.isCoreTile(c, r)) { - EXPECT_EQ(deviceModel.getLocalMemorySize(c, r), - targetModel.getLocalMemorySize()) - << "local size don't agree"; - } -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - MemTilesAgree) { - auto [c, r] = GetParam(); - - EXPECT_EQ(deviceModel.isMemTile(c, r), targetModel.isMemTile(c, r)) - << "Mem tile disagree; " << deviceModel.getTileType(c, r) << " " << c - << ", " << r << "\n"; - if (deviceModel.isMemTile(c, r)) { - EXPECT_EQ(deviceModel.getMemTileSize(c, r), targetModel.getMemTileSize()) - << "memtile memory size don't agree; " << c << ", " << r << "\n"; - } -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - ShimNOCTileAgree) { - auto [c, r] = GetParam(); - EXPECT_EQ(deviceModel.isShimNOCTile(c, r), targetModel.isShimNOCTile(c, r)) - << "ShimNOC tile disagree; " << deviceModel.getTileType(c, r); -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - ShimPLTileAgree) { - auto [c, r] = GetParam(); - EXPECT_EQ(deviceModel.isShimPLTile(c, r), targetModel.isShimPLTile(c, r)) - << "ShimPL tile disagree; " << deviceModel.getTileType(c, r); -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - NumLocksAgree) { - auto [c, r] = GetParam(); - EXPECT_EQ(deviceModel.getNumLocks(c, r), targetModel.getNumLocks(c, r)); -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - NumBDsAgree) { - auto [c, r] = GetParam(); - EXPECT_EQ(deviceModel.getNumBDs(c, r), targetModel.getNumBDs(c, r)); -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - MemWestAgree) { - auto [c, r] = GetParam(); - TileLoc dloc = {c, r}; - xilinx::AIE::TileID tloc = {c, r}; - auto d = deviceModel.getMemWest(dloc); - auto t = targetModel.getMemWest(tloc); - - EXPECT_EQ(d.has_value(), t.has_value()) << "MemWest disagree on exist "; - if (d.has_value()) { - EXPECT_EQ(d->col, t->col) << "MemWest disagree on col"; - EXPECT_EQ(d->row, t->row) << "MemWest disagree on row"; - } -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - MemEastAgree) { - auto [c, r] = GetParam(); - TileLoc dloc = {c, r}; - xilinx::AIE::TileID tloc = {c, r}; - auto d = deviceModel.getMemEast(dloc); - auto t = targetModel.getMemEast(tloc); - EXPECT_EQ(d.has_value(), t.has_value()) << "MemEast disagree on exist "; - if (d.has_value()) { - EXPECT_EQ(d->col, t->col) << "MemEast disagree on col"; - EXPECT_EQ(d->row, t->row) << "MemEast disagree on row"; - } -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - MemNorthAgree) { - auto [c, r] = GetParam(); - TileLoc dloc = {c, r}; - xilinx::AIE::TileID tloc = {c, r}; - auto d = deviceModel.getMemNorth(dloc); - auto t = targetModel.getMemNorth(tloc); - EXPECT_EQ(d.has_value(), t.has_value()) << "MemNorth disagree on exist "; - if (d.has_value()) { - EXPECT_EQ(d->col, t->col) << "MemNorth disagree on col"; - EXPECT_EQ(d->row, t->row) << "MemNorth disagree on row"; - } -} - -TEST_P(AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - MemSouthAgree) { - auto [c, r] = GetParam(); - TileLoc dloc = {c, r}; - xilinx::AIE::TileID tloc = {c, r}; - auto d = deviceModel.getMemSouth(dloc); - auto t = targetModel.getMemSouth(tloc); - EXPECT_EQ(d.has_value(), t.has_value()) << "MemSouth disagree on exist "; - if (d.has_value()) { - EXPECT_EQ(d->col, t->col) << "MemSouth disagree on col"; - EXPECT_EQ(d->row, t->row) << "MemSouth disagree on row"; - } -} - -TEST_P(AMDAIENPUDeviceModelParameterizedAllPairsTimesAllPairsNPU4ColTestFixture, - HasMemWestAgree) { - auto [c, r, cc, rr] = GetParam(); - EXPECT_EQ(deviceModel.hasMemWest(c, r, cc, rr), - targetModel.isMemWest(c, r, cc, rr)) - << "hasMemWest disagree"; -} - -TEST_P(AMDAIENPUDeviceModelParameterizedAllPairsTimesAllPairsNPU4ColTestFixture, - HasMemEastAgree) { - auto [c, r, cc, rr] = GetParam(); - EXPECT_EQ(deviceModel.hasMemEast(c, r, cc, rr), - targetModel.isMemEast(c, r, cc, rr)) - << "hasMemEast disagree"; -} - -TEST_P(AMDAIENPUDeviceModelParameterizedAllPairsTimesAllPairsNPU4ColTestFixture, - HasMemNorthAgree) { - auto [c, r, cc, rr] = GetParam(); - EXPECT_EQ(deviceModel.hasMemNorth(c, r, cc, rr), - targetModel.isMemNorth(c, r, cc, rr)) - << "hasMemNorth disagree"; -} - -TEST_P(AMDAIENPUDeviceModelParameterizedAllPairsTimesAllPairsNPU4ColTestFixture, - HasMemSouthAgree) { - auto [c, r, cc, rr] = GetParam(); - EXPECT_EQ(deviceModel.hasMemSouth(c, r, cc, rr), - targetModel.isMemSouth(c, r, cc, rr)) - << "hasMemSouth disagree"; -} - -const std::map, std::tuple, - std::less<>> - NumSourceSwitchBoxConnectionsFails{ - // c, r, port, deviceModelNumSrc, targetModelNumSrc - {{0, 0, StrmSwPortType::TRACE}, {2, 1}}, - // trace - {{1, 0, StrmSwPortType::TRACE}, {2, 1}}, - {{2, 0, StrmSwPortType::TRACE}, {2, 1}}, - {{3, 0, StrmSwPortType::TRACE}, {2, 1}}, - {{4, 0, StrmSwPortType::TRACE}, {2, 1}}, - // east - {{3, 0, StrmSwPortType::EAST}, {4, 0}}, - {{3, 2, StrmSwPortType::EAST}, {4, 0}}, - {{3, 3, StrmSwPortType::EAST}, {4, 0}}, - {{3, 4, StrmSwPortType::EAST}, {4, 0}}, - {{3, 5, StrmSwPortType::EAST}, {4, 0}}}; - -TEST_P( - AMDAIENPUDeviceModelParameterizedAllPairsTimesAllSwitchesNPU4ColTestFixture, - NumSourceSwitchBoxConnections) { - auto [c, r, strmSwPortType] = GetParam(); - auto srcSw = static_cast(strmSwPortType); - auto wireB = STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE(srcSw); - auto deviceModelNumSrc = - deviceModel.getNumSourceSwitchBoxConnections(c, r, srcSw); - auto targetModelNumSrc = - targetModel.getNumSourceSwitchboxConnections(c, r, wireB); - const auto tup = std::make_tuple(c, r, srcSw); - if (NumSourceSwitchBoxConnectionsFails.count(tup)) { - auto [d, t] = NumSourceSwitchBoxConnectionsFails.at(tup); - EXPECT_EQ(deviceModelNumSrc, d); - EXPECT_EQ(targetModelNumSrc, t); - } else - EXPECT_EQ(deviceModelNumSrc, targetModelNumSrc) - << "diff src # for switch typ: " << srcSw << "\n"; -} - -const std::map, std::tuple, - std::less<>> - NumDestSwitchBoxConnectionsFails{ - // c, r, port, deviceModelNumSrc, targetModelNumSrc - {{3, 0, StrmSwPortType::EAST}, {4, 0}}, - {{3, 2, StrmSwPortType::EAST}, {4, 0}}, - {{3, 3, StrmSwPortType::EAST}, {4, 0}}, - {{3, 4, StrmSwPortType::EAST}, {4, 0}}, - {{3, 5, StrmSwPortType::EAST}, {4, 0}}}; - -TEST_P( - AMDAIENPUDeviceModelParameterizedAllPairsTimesAllSwitchesNPU4ColTestFixture, - NumDestSwitchBoxConnections) { - auto [c, r, strmSwPortType] = GetParam(); - auto dstSw = static_cast(strmSwPortType); - auto wireB = STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE(dstSw); - auto deviceModelNumDst = - deviceModel.getNumDestSwitchBoxConnections(c, r, dstSw); - auto targetModelNumDst = - targetModel.getNumDestSwitchboxConnections(c, r, wireB); - const auto tup = std::make_tuple(c, r, dstSw); - if (NumDestSwitchBoxConnectionsFails.count(tup)) { - auto [d, t] = NumDestSwitchBoxConnectionsFails.at(tup); - EXPECT_EQ(deviceModelNumDst, d); - EXPECT_EQ(targetModelNumDst, t); - - } else - EXPECT_EQ(deviceModelNumDst, targetModelNumDst) - << "diff dest # for switch typ: " << dstSw << "\n"; -} - -class AMDAIENPUDeviceModelParameterizedMemtileConnectivityNPU4ColTestFixture - : public AMDAIENPUDeviceModelParameterizedTupleTestNPU4ColFixture {}; - -#define X false -#define O true - -const std::vector> MEMTILE_CONNECTIVITY = { - {O, X, X, X, X, X, O, O, O, O, O, O, O, O, O, O, O}, - {X, O, X, X, X, X, O, O, O, O, O, O, O, O, O, O, O}, - {X, X, O, X, X, X, O, O, O, O, O, O, O, O, O, O, O}, - {X, X, X, O, X, X, O, O, O, O, O, O, O, O, O, O, O}, - {X, X, X, X, O, X, O, O, O, O, O, O, O, O, O, O, O}, - {X, X, X, X, X, O, O, O, O, O, O, O, O, O, O, O, O}, - {X, X, X, X, X, O, X, O, O, O, O, O, O, O, O, O, O}, - {O, O, O, O, O, O, O, O, X, X, X, O, X, X, X, X, X}, - {O, O, O, O, O, O, O, X, O, X, X, X, O, X, X, X, X}, - {O, O, O, O, O, O, O, X, X, O, X, X, X, O, X, X, X}, - {O, O, O, O, O, O, O, X, X, X, O, X, X, X, O, X, X}, - {O, O, O, O, O, O, O, X, X, X, X, X, X, X, X, O, X}, - {O, O, O, O, O, O, O, X, X, X, X, X, X, X, X, X, O}, - {O, O, O, O, O, O, O, O, X, X, X, O, X, X, X, X, X}, - {O, O, O, O, O, O, O, X, O, X, X, X, O, X, X, X, X}, - {O, O, O, O, O, O, O, X, X, O, X, X, X, O, X, X, X}, - {O, O, O, O, O, O, O, X, X, X, O, X, X, X, O, X, X}, - {X, X, X, X, X, O, X, O, O, O, O, X, X, X, X, X, X}}; - -#undef X -#undef O - -TEST_P(AMDAIENPUDeviceModelParameterizedMemtileConnectivityNPU4ColTestFixture, - VerifyAIERTAIE2MemTileConnectivity) { - auto [slavePhyPort, masterPhyPort] = GetParam(); - ::StrmSwPortType slaveLogicalPortType, masterLogicalPortType; - uint8_t slaveLogicalPortNum, masterLogicalPortNum; - - XAie_LocType tileLoc = XAie_TileLoc(/*col=*/3, /*row=*/1); - XAie_StrmSwPhysicalToLogicalPort(&deviceModel.devInst, tileLoc, - XAIE_STRMSW_SLAVE, slavePhyPort, - &slaveLogicalPortType, &slaveLogicalPortNum); - XAie_StrmSwPhysicalToLogicalPort( - &deviceModel.devInst, tileLoc, XAIE_STRMSW_MASTER, masterPhyPort, - &masterLogicalPortType, &masterLogicalPortNum); - - AieRC RC = _XAieMl_MemTile_StrmSwCheckPortValidity( - slaveLogicalPortType, slaveLogicalPortNum, masterLogicalPortType, - masterLogicalPortNum); - - bool connected = MEMTILE_CONNECTIVITY[slavePhyPort][masterPhyPort]; - EXPECT_EQ(RC == XAIE_OK, connected) - << "slave: " << slaveLogicalPortType << (int)slaveLogicalPortNum << ": " - << slavePhyPort << "\n" - << "master: " << masterLogicalPortType << (int)masterLogicalPortNum - << ": " << masterPhyPort << "\n\n"; -} - -TEST_P(AMDAIENPUDeviceModelParameterizedSixTupleNPU4ColTestFixture, - IsLegalMemtileConnection) { - auto [c, r, srcStrmSwPortType, destStrmSwPortType, srcChan, dstChan] = - GetParam(); - - // TODO(max): maybe there's a way in gtest for the generators to be - // parameterized? - if ((srcStrmSwPortType == StrmSwPortType::CTRL || - destStrmSwPortType == StrmSwPortType::CTRL) && - (srcChan > 0 || dstChan > 0)) { - return; - } - if (srcStrmSwPortType == StrmSwPortType::TRACE && srcChan > 0) return; - if (srcStrmSwPortType == StrmSwPortType::NORTH && srcChan > 3) return; - if (destStrmSwPortType == StrmSwPortType::SOUTH && dstChan > 3) return; - - auto srcSw = srcStrmSwPortType; - auto srcWireB = STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE(srcSw); - if (deviceModel.isMemTile(c, r)) { - auto destSw = destStrmSwPortType; - auto destWireb = STRM_SW_PORT_TYPE_TO_WIRE_BUNDLE(destSw); - auto deviceModelIsLegal = deviceModel.isLegalTileConnection( - c, r, srcSw, srcChan, destSw, dstChan); - auto targetModelIsLegal = targetModel.isLegalTileConnection( - c, r, srcWireB, srcChan, destWireb, dstChan); - - EXPECT_EQ(deviceModelIsLegal, targetModelIsLegal) - << "c,r: " << c << ", " << r << "\n" - << "src: " << to_string(srcSw) << ", " << srcChan << "\n" - << "dst: " << to_string(destSw) << ", " << dstChan << "\n\n"; - } -} - -TEST(IsLegalMemtileConnectionSouth4, Test0) { - AMDAIEDeviceModel deviceModel = - mlir::iree_compiler::AMDAIE::getDeviceModel(AMDAIEDevice::npu1_4col); - const xilinx::AIE::AIETargetModel &targetModel = - xilinx::AIE::getTargetModel(xilinx::AIE::AIEDevice::npu1_4col); - - auto deviceModelIsLegal = deviceModel.isLegalTileConnection( - 0, 1, StrmSwPortType::DMA, 2, StrmSwPortType::SOUTH, 4); - auto targetModelIsLegal = targetModel.isLegalTileConnection( - 0, 1, xilinx::AIE::WireBundle::DMA, 2, xilinx::AIE::WireBundle::South, 4); - EXPECT_EQ(deviceModelIsLegal, targetModelIsLegal); -} - -// setting a partition (i.e. using XAie_SetupPartitionConfig) actually changes -// the devNCols to the number of cols in the partition -// https://github.com/Xilinx/aie-rt/blob/38fcf1f9eb7c678defaf8c19ffb50a679b644452/driver/src/global/xaiegbl.c#L120 -#define NPU1_4COL_NUM_COLS 4 -#define NPU1_4COL_NUM_ROWS 6 - -INSTANTIATE_TEST_SUITE_P( - NumRowsNumColsTests, - AMDAIENPUDeviceModelParameterizedNumColsNumRowsNPU4ColTestFixture, - ::testing::Combine(::testing::Range(0, NPU1_4COL_NUM_COLS), - ::testing::Range(0, NPU1_4COL_NUM_ROWS))); - -INSTANTIATE_TEST_SUITE_P( - AllPairsTimesAllPairsTests, - AMDAIENPUDeviceModelParameterizedAllPairsTimesAllPairsNPU4ColTestFixture, - ::testing::Combine(::testing::Range(0, NPU1_4COL_NUM_COLS), - ::testing::Range(0, NPU1_4COL_NUM_ROWS), - ::testing::Range(0, NPU1_4COL_NUM_COLS), - ::testing::Range(0, NPU1_4COL_NUM_ROWS))); - -INSTANTIATE_TEST_SUITE_P( - AllPairsTimesAllSwitchesTests, - AMDAIENPUDeviceModelParameterizedAllPairsTimesAllSwitchesNPU4ColTestFixture, - ::testing::Combine( - ::testing::Range(0, NPU1_4COL_NUM_COLS), - ::testing::Range(0, NPU1_4COL_NUM_ROWS), - ::testing::Values(StrmSwPortType::CORE, StrmSwPortType::DMA, - StrmSwPortType::CTRL, StrmSwPortType::FIFO, - StrmSwPortType::SOUTH, StrmSwPortType::WEST, - StrmSwPortType::NORTH, StrmSwPortType::EAST, - StrmSwPortType::TRACE))); - -INSTANTIATE_TEST_SUITE_P( - VerifyAIERTAIE2MemTileConnectivity, - AMDAIENPUDeviceModelParameterizedMemtileConnectivityNPU4ColTestFixture, - ::testing::Combine(::testing::Range(0, (int)MEMTILE_CONNECTIVITY.size()), - ::testing::Range(0, - (int)MEMTILE_CONNECTIVITY[0].size()))); - -#define MAX_CHANNELS 6 - -// Figure 6-9: Stream-switch ports and connectivity matrix -const std::vector legalSlaves{ - StrmSwPortType::DMA, StrmSwPortType::CTRL, StrmSwPortType::SOUTH, - StrmSwPortType::NORTH, StrmSwPortType::TRACE}; -const std::vector legalMasters{ - StrmSwPortType::DMA, StrmSwPortType::CTRL, StrmSwPortType::SOUTH, - StrmSwPortType::NORTH}; - -INSTANTIATE_TEST_SUITE_P( - IsLegalMemtileConnectionTests, - AMDAIENPUDeviceModelParameterizedSixTupleNPU4ColTestFixture, - ::testing::Combine(::testing::Range(0, NPU1_4COL_NUM_COLS), - ::testing::Range(0, NPU1_4COL_NUM_ROWS), - ::testing::ValuesIn(legalSlaves), - ::testing::ValuesIn(legalMasters), - ::testing::Range(0, MAX_CHANNELS), - ::testing::Range(0, MAX_CHANNELS))); - -} // namespace - -int main(int argc, char **argv) { - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} From 550cedab69f164105b0ee2d440159cbd5953f260 Mon Sep 17 00:00:00 2001 From: Maksim Levental Date: Wed, 7 Aug 2024 17:57:30 -0700 Subject: [PATCH 12/12] Update build_test_cpp.sh --- build_tools/ci/build_test_cpp.sh | 1 - compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp | 12 +++++------- compiler/plugins/target/AMD-AIE/aie/AIEDialect.h | 1 - compiler/plugins/target/AMD-AIE/aie/AIEOps.td | 4 +--- compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp | 3 --- 5 files changed, 6 insertions(+), 15 deletions(-) diff --git a/build_tools/ci/build_test_cpp.sh b/build_tools/ci/build_test_cpp.sh index d462da28d..753bcd3cf 100644 --- a/build_tools/ci/build_test_cpp.sh +++ b/build_tools/ci/build_test_cpp.sh @@ -7,7 +7,6 @@ repo_root="$(cd $this_dir/../.. && pwd)" iree_dir="$(cd $repo_root/../iree && pwd)" build_dir="$repo_root/iree-build" install_dir="$repo_root/iree-install" -rm -rf "$build_dir" "$install_dir" mkdir -p "$build_dir" build_dir="$(cd $build_dir && pwd)" cache_dir="${cache_dir:-}" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp index 89beea625..d790c074f 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEDialect.cpp @@ -264,14 +264,12 @@ TileOp getTileOp(mlir::Operation &op) { return llvm::cast(t.getDefiningOp()); } -TileOp CoreOp::getTileOp() { return ::xilinx::AIE::getTileOp(*getOperation()); } +TileOp CoreOp::getTileOp() { return xilinx::AIE::getTileOp(*getOperation()); } -TileOp BufferOp::getTileOp() { - return ::xilinx::AIE::getTileOp(*getOperation()); -} +TileOp BufferOp::getTileOp() { return xilinx::AIE::getTileOp(*getOperation()); } TileOp ShimDMAOp::getTileOp() { - return ::xilinx::AIE::getTileOp(*getOperation()); + return xilinx::AIE::getTileOp(*getOperation()); } int32_t getBufferElementTypeWidthInBytes(DMABDOp &op) { @@ -304,9 +302,9 @@ CoreOp getCoreOp(TileOp &op) { return nullptr; } -MemOp TileOp::getMemOp() { return ::xilinx::AIE::getMemOp(*this); } +MemOp TileOp::getMemOp() { return xilinx::AIE::getMemOp(*this); } -CoreOp TileOp::getCoreOp() { return ::xilinx::AIE::getCoreOp(*this); } +CoreOp TileOp::getCoreOp() { return xilinx::AIE::getCoreOp(*this); } void collectBuffers(DeviceOp &device, llvm::DenseMap symbolizeAIEDevice( #define GET_ATTRDEF_CLASSES #include "aie/AIEAttrs.h.inc" -// include TableGen generated Op definitions #define GET_OP_CLASSES #include "aie/AIEOps.h.inc" diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td index edbb52407..c8b3399df 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEOps.td +++ b/compiler/plugins/target/AMD-AIE/aie/AIEOps.td @@ -233,7 +233,6 @@ def AIE_PacketRuleOp: AIE_Op<"rule"> { }]; } - def AIE_PacketFlowOp: AIE_Op<"packet_flow", [SingleBlockImplicitTerminator<"EndOp">]> { let summary = "Packet switched flow"; let arguments = ( @@ -613,7 +612,6 @@ def AIE_ObjectFifoSubviewAccessOp : AIE_Op<"objectfifo.subview.access"> { $subview `[` $index `]` attr-dict `:` type($subview) `->` type($output) }]; - // Allow building an AIE_ObjectFifoSubviewAccessOp with just a subview value and an index. let builders = [ OpBuilder<(ins "mlir::Value":$subview, "size_t":$index)> ]; @@ -645,7 +643,7 @@ def AIE_ShimDMAOp: AIE_Op<"shim_dma", [ }]; } -// legacy tests +// legacy to support tests def AIE_ObjectFifoRegisterExternalBuffersOp: AIE_Op<"objectfifo.register_external_buffers"> { let summary = "Registers external buffers to given object fifo shim tile(s) to use in the associated shim DMA(s)"; diff --git a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp index dcd4d417a..001f2ace0 100644 --- a/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp +++ b/compiler/plugins/target/AMD-AIE/aie/AIEXDialect.cpp @@ -60,8 +60,6 @@ AIEX::NpuDmaMemcpyNdOp::getSizesInAddressGranularity() { return sizes; } -/* Calculates the offset value to be written to the - */ int64_t AIEX::NpuDmaMemcpyNdOp::getOffsetInBytes() { llvm::SmallVector offsets = llvm::map_to_vector( llvm::reverse(getMixedOffsets()), @@ -108,7 +106,6 @@ ParseResult AIEX::RuntimeSequenceOp::parse(OpAsmParser &parser, return argParseResult; } - // Body auto *body = result.addRegion(); ParseResult bodyParseResult = parser.parseRegion(*body, entryArgs, false); if (bodyParseResult) {