From 751a78e9ce2e080b9efd752af0f56e3003e30683 Mon Sep 17 00:00:00 2001 From: abisca Date: Fri, 2 Feb 2024 16:32:04 -0700 Subject: [PATCH 01/51] Add new ConfigureCascadeOp and CascadeDir attribute to AIE dialect. Add tests. Add mlir_aie_configure_cascade target to AIE2 that generates libXAIE calls from ConfigureCascadeOps. --- include/aie/Dialect/AIE/IR/AIEAttrs.td | 11 ++++++++ include/aie/Dialect/AIE/IR/AIEOps.td | 24 +++++++++++++++++ lib/Dialect/AIE/IR/AIEDialect.cpp | 24 +++++++++++++++++ lib/Targets/AIETargetXAIEV2.cpp | 16 +++++++++++ test/dialect/AIE/bad_cascade.mlir | 35 +++++++++++++++++++++++++ test/dialect/AIE/cascade_configure.mlir | 20 ++++++++++++++ 6 files changed, 130 insertions(+) create mode 100644 test/dialect/AIE/bad_cascade.mlir create mode 100644 test/dialect/AIE/cascade_configure.mlir diff --git a/include/aie/Dialect/AIE/IR/AIEAttrs.td b/include/aie/Dialect/AIE/IR/AIEAttrs.td index 96dfb4aec0..c4b7a4e9ed 100644 --- a/include/aie/Dialect/AIE/IR/AIEAttrs.td +++ b/include/aie/Dialect/AIE/IR/AIEAttrs.td @@ -144,4 +144,15 @@ def BDDimLayoutArrayArrayAttr : ArrayOfAttr< /*eltName*/BDDimLayoutArrayAttr.cppClassName >; +def CascadeDir: I32EnumAttr<"CascadeDir", "Directions for cascade", + [ + I32EnumAttrCase<"South", 0>, + I32EnumAttrCase<"West", 1>, + I32EnumAttrCase<"North", 2>, + I32EnumAttrCase<"East", 3> + ]> { + + let cppNamespace = "xilinx::AIE"; +} + #endif // AIE_ATTRS \ No newline at end of file diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index 923752e38d..0f5c025b18 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -1343,6 +1343,30 @@ def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { }]; } +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:$cascadeValue)> { let summary = "An op to read from a cascading stream from a neighboring core"; let description = [{ diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 743f0bdd03..28568c45c7 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -864,6 +864,30 @@ ObjectFifoCreateOp ObjectFifoRegisterProcessOp::getObjectFifo() { return {}; } +//===----------------------------------------------------------------------===// +// ConfigureCascadeOp +//===----------------------------------------------------------------------===// + +LogicalResult ConfigureCascadeOp::verify() { + const auto &targetModel = getTargetModel(*this); + CascadeDir inputDir = getInputDir(); + CascadeDir outputDir = getOutputDir(); + if (targetModel.getTargetArch() == AIEArch::AIE2) { + if (inputDir == CascadeDir::South || inputDir == CascadeDir::East) { + return emitOpError("input direction of cascade must be North or West on ") + << stringifyAIEArch(targetModel.getTargetArch()); + } + if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { + return emitOpError("output direction of cascade must be South or East on ") + << stringifyAIEArch(targetModel.getTargetArch()); + } + } else { + return emitOpError("cascade not supported in ") + << stringifyAIEArch(targetModel.getTargetArch()); + } + return success(); +} + //===----------------------------------------------------------------------===// // PutCascadeOp //===----------------------------------------------------------------------===// diff --git a/lib/Targets/AIETargetXAIEV2.cpp b/lib/Targets/AIETargetXAIEV2.cpp index eaa763a23b..395bd9dc22 100644 --- a/lib/Targets/AIETargetXAIEV2.cpp +++ b/lib/Targets/AIETargetXAIEV2.cpp @@ -765,6 +765,22 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { output << "return XAIE_OK;\n"; output << "} // mlir_aie_configure_switchboxes\n\n"; + //--------------------------------------------------------------------------- + // mlir_aie_configure_cascade + //--------------------------------------------------------------------------- + output << "int mlir_aie_configure_cascade(" << ctx_p << ") {\n"; + for (auto configOp : targetOp.getOps()) { + TileOp tile = dyn_cast(configOp.getTile().getDefiningOp()); + int col = tile.colIndex(); + int row = tile.rowIndex(); + output << "XAie_CoreConfigAccumulatorControl(" << deviceInstRef << ", " + << "XAie_TileLoc(" << col << ", " << row << "), " + << stringifyCascadeDir(configOp.getInputDir()).upper() << ", " + << stringifyCascadeDir(configOp.getOutputDir()).upper() << ");\n"; + } + output << "return XAIE_OK;\n"; + output << "} // mlir_aie_configure_cascade\n\n"; + //--------------------------------------------------------------------------- // Output Buffer Accessors //--------------------------------------------------------------------------- diff --git a/test/dialect/AIE/bad_cascade.mlir b/test/dialect/AIE/bad_cascade.mlir new file mode 100644 index 0000000000..7e14b5fe1a --- /dev/null +++ b/test/dialect/AIE/bad_cascade.mlir @@ -0,0 +1,35 @@ +//===- bad_cascade.mlir ----------------------------------------*- MLIR -*-===// +// +// 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 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// RUN: not aie-opt -split-input-file %s 2>&1 | FileCheck %s +// CHECK: error{{.*}}'aie.configure_cascade' op input direction of cascade must be North or West on AIE2 + +aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + aie.configure_cascade(%t13, East, South) +} + +// ----- + +// CHECK: error{{.*}}'aie.configure_cascade' op output direction of cascade must be South or East on AIE2 + +aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + aie.configure_cascade(%t13, North, West) +} + +// ----- + +// CHECK: error{{.*}}'aie.configure_cascade' op cascade not supported in AIE1 + +aie.device(xcvc1902) { + %t13 = aie.tile(1, 3) + aie.configure_cascade(%t13, North, East) +} diff --git a/test/dialect/AIE/cascade_configure.mlir b/test/dialect/AIE/cascade_configure.mlir new file mode 100644 index 0000000000..89c8399f67 --- /dev/null +++ b/test/dialect/AIE/cascade_configure.mlir @@ -0,0 +1,20 @@ +//===- cascade_configure.mlir -----------------------------------*- MLIR -*-===// +// +// 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 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// RUN: aie-opt %s + +module @test { + aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + %t23 = aie.tile(2, 3) + aie.configure_cascade(%t13, West, East) + aie.configure_cascade(%t23, North, South) + } +} From dbe8e72ce12c9fb29a342f5ccac69129fe9b8b49 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Fri, 2 Feb 2024 15:48:23 -0800 Subject: [PATCH 02/51] Update lib/Dialect/AIE/IR/AIEDialect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/IR/AIEDialect.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 28568c45c7..9ebf433090 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -875,7 +875,7 @@ LogicalResult ConfigureCascadeOp::verify() { if (targetModel.getTargetArch() == AIEArch::AIE2) { if (inputDir == CascadeDir::South || inputDir == CascadeDir::East) { return emitOpError("input direction of cascade must be North or West on ") - << stringifyAIEArch(targetModel.getTargetArch()); + << stringifyAIEArch(targetModel.getTargetArch()); } if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { return emitOpError("output direction of cascade must be South or East on ") From 4bfae994e4d03c91d98c0f9e39ad02a76319b961 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Fri, 2 Feb 2024 15:48:29 -0800 Subject: [PATCH 03/51] Update lib/Dialect/AIE/IR/AIEDialect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/IR/AIEDialect.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 9ebf433090..64b4164bc5 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -878,8 +878,9 @@ LogicalResult ConfigureCascadeOp::verify() { << stringifyAIEArch(targetModel.getTargetArch()); } if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { - return emitOpError("output direction of cascade must be South or East on ") - << stringifyAIEArch(targetModel.getTargetArch()); + return emitOpError( + "output direction of cascade must be South or East on ") + << stringifyAIEArch(targetModel.getTargetArch()); } } else { return emitOpError("cascade not supported in ") From ce318fda0e65d4343792edd6879353d9a35e6e3f Mon Sep 17 00:00:00 2001 From: abisca Date: Mon, 5 Feb 2024 15:10:09 -0700 Subject: [PATCH 04/51] Update aie2 cascade unit test --- test/unit_tests/aie2/03_cascade_core_functions/aie.mlir | 3 +++ test/unit_tests/aie2/03_cascade_core_functions/test.cpp | 8 ++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir b/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir index 90070c33dc..50a4765f1e 100644 --- a/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir +++ b/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir @@ -20,6 +20,9 @@ module { %tile13 = aie.tile(1, 3) %tile23 = aie.tile(2, 3) + aie.configure_cascade(%tile13, West, East) + aie.configure_cascade(%tile23, West, East) + %buf13_0 = aie.buffer(%tile13) { sym_name = "a" } : memref<256xi32> %buf23_0 = aie.buffer(%tile23) { sym_name = "c" } : memref<256xi32> diff --git a/test/unit_tests/aie2/03_cascade_core_functions/test.cpp b/test/unit_tests/aie2/03_cascade_core_functions/test.cpp index 70fb04d49c..30626d4be3 100644 --- a/test/unit_tests/aie2/03_cascade_core_functions/test.cpp +++ b/test/unit_tests/aie2/03_cascade_core_functions/test.cpp @@ -31,13 +31,9 @@ int main(int argc, char *argv[]) { mlir_aie_configure_cores(_xaie); mlir_aie_configure_switchboxes(_xaie); mlir_aie_configure_dmas(_xaie); + mlir_aie_configure_cascade(); mlir_aie_initialize_locks(_xaie); - - // FIXME: model in MLIR - XAie_CoreConfigAccumulatorControl(&(_xaie->DevInst), XAie_TileLoc(1, 3), WEST, - EAST); - XAie_CoreConfigAccumulatorControl(&(_xaie->DevInst), XAie_TileLoc(2, 3), WEST, - EAST); + int errors = 0; mlir_aie_write_buffer_a(_xaie, 3, 7); From 8c136ca8e12fe16a583a8419a9ec5a2b3e89348a Mon Sep 17 00:00:00 2001 From: abisca Date: Mon, 5 Feb 2024 15:10:58 -0700 Subject: [PATCH 05/51] Add cascade config to ipu target. --- lib/Targets/AIETargetCDODirect.cpp | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index e4ab243ff2..bb61a706e2 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -108,6 +108,14 @@ static const std::map {WireBundle::Trace, StrmSwPortType::TRACE}, }; +static const std::map + CASCADE_DIR_TO_STRM_SW_PORT_TYPE = { + {CascadeDir::South, StrmSwPortType::SOUTH}, + {CascadeDir::West, StrmSwPortType::WEST}, + {CascadeDir::North, StrmSwPortType::NORTH}, + {CascadeDir::East, StrmSwPortType::EAST}, +}; + // https://stackoverflow.com/a/32230306 template @@ -697,6 +705,18 @@ struct AIEControl { WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle()), connectOp.destIndex()); } + + // Cascade configuration + for (auto configOp : targetOp.getOps()) { + TileOp tile = dyn_cast(configOp.getTile().getDefiningOp()); + auto tileLoc = + XAie_TileLoc(tile.getCol(), tile.getRow()); + TRY_XAIE_API_EMIT_ERROR(targetOp, XAie_CoreConfigAccumulatorControl, + &devInst, tileLoc, + CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getInputDir()), + CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getOutputDir())); + } + return success(); } From 54afbc6591338c048d291fd0745feaf8118e9658 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Mon, 5 Feb 2024 15:39:20 -0800 Subject: [PATCH 06/51] Update lib/Targets/AIETargetCDODirect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Targets/AIETargetCDODirect.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index bb61a706e2..6cd917da6c 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -709,12 +709,11 @@ struct AIEControl { // Cascade configuration for (auto configOp : targetOp.getOps()) { TileOp tile = dyn_cast(configOp.getTile().getDefiningOp()); - auto tileLoc = - XAie_TileLoc(tile.getCol(), tile.getRow()); - TRY_XAIE_API_EMIT_ERROR(targetOp, XAie_CoreConfigAccumulatorControl, - &devInst, tileLoc, - CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getInputDir()), - CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getOutputDir())); + auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); + TRY_XAIE_API_EMIT_ERROR( + targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, + CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getInputDir()), + CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getOutputDir())); } return success(); From 85754d6e7a2f28c3bc36074538bdb68e6fb4e799 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Mon, 5 Feb 2024 15:39:29 -0800 Subject: [PATCH 07/51] Update test/unit_tests/aie2/03_cascade_core_functions/test.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- test/unit_tests/aie2/03_cascade_core_functions/test.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/test/unit_tests/aie2/03_cascade_core_functions/test.cpp b/test/unit_tests/aie2/03_cascade_core_functions/test.cpp index 30626d4be3..128bf123f7 100644 --- a/test/unit_tests/aie2/03_cascade_core_functions/test.cpp +++ b/test/unit_tests/aie2/03_cascade_core_functions/test.cpp @@ -33,7 +33,6 @@ int main(int argc, char *argv[]) { mlir_aie_configure_dmas(_xaie); mlir_aie_configure_cascade(); mlir_aie_initialize_locks(_xaie); - int errors = 0; mlir_aie_write_buffer_a(_xaie, 3, 7); From 5b296d2161ae4760cdef14c90b68bc8ce5ed0eff Mon Sep 17 00:00:00 2001 From: abisca Date: Mon, 5 Feb 2024 17:37:20 -0700 Subject: [PATCH 08/51] Replace dyn_cast with cast, where applicable. --- lib/Targets/AIETargetCDODirect.cpp | 6 +++--- lib/Targets/AIETargetXAIEV2.cpp | 14 +++++++------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index bb61a706e2..f4ea761d41 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -631,7 +631,7 @@ struct AIEControl { int arbiter = -1; for (auto val : connectOp.getAmsels()) { - AMSelOp amsel = dyn_cast(val.getDefiningOp()); + AMSelOp amsel = cast(val.getDefiningOp()); arbiter = amsel.arbiterIndex(); int msel = amsel.getMselValue(); mask |= (1 << msel); @@ -657,7 +657,7 @@ struct AIEControl { Block &block = connectOp.getRules().front(); for (auto slotOp : block.getOps()) { AMSelOp amselOp = - dyn_cast(slotOp.getAmsel().getDefiningOp()); + cast(slotOp.getAmsel().getDefiningOp()); int arbiter = amselOp.arbiterIndex(); int msel = amselOp.getMselValue(); TRY_XAIE_API_EMIT_ERROR( @@ -708,7 +708,7 @@ struct AIEControl { // Cascade configuration for (auto configOp : targetOp.getOps()) { - TileOp tile = dyn_cast(configOp.getTile().getDefiningOp()); + TileOp tile = cast(configOp.getTile().getDefiningOp()); auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); TRY_XAIE_API_EMIT_ERROR(targetOp, XAie_CoreConfigAccumulatorControl, diff --git a/lib/Targets/AIETargetXAIEV2.cpp b/lib/Targets/AIETargetXAIEV2.cpp index 395bd9dc22..11b0e1c424 100644 --- a/lib/Targets/AIETargetXAIEV2.cpp +++ b/lib/Targets/AIETargetXAIEV2.cpp @@ -148,7 +148,7 @@ mlir::LogicalResult generateDMAConfig(OpType memOp, raw_ostream &output, bool hasAcq = false, hasRel = false; int acqLockID = 0, relLockID = 0; for (auto op : block.template getOps()) { - LockOp lock = dyn_cast(op.getLock().getDefiningOp()); + LockOp lock = cast(op.getLock().getDefiningOp()); int lockCol = lock.colIndex(); int lockRow = lock.rowIndex(); int lockID = lock.getLockIDValue(); @@ -617,11 +617,11 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { dyn_cast(switchboxOp.getTile().getDefiningOp())) { // parameterize streamswitch's configuration isParam = true; - HerdOp sourceHerd = dyn_cast(sel.getStartHerd().getDefiningOp()); + HerdOp sourceHerd = cast(sel.getStartHerd().getDefiningOp()); std::string sourceHerdName(sourceHerd.name().getValue()); - IterOp iterX = dyn_cast(sel.getIterX().getDefiningOp()); - IterOp iterY = dyn_cast(sel.getIterY().getDefiningOp()); + IterOp iterX = cast(sel.getIterX().getDefiningOp()); + IterOp iterY = cast(sel.getIterY().getDefiningOp()); int startXValue = iterX.getStartValue(); int endXValue = iterX.getEndValue(); int strideXValue = iterX.getStrideValue(); @@ -654,7 +654,7 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { int mask = 0; int arbiter = -1; for (auto val : connectOp.getAmsels()) { - AMSelOp amsel = dyn_cast(val.getDefiningOp()); + AMSelOp amsel = cast(val.getDefiningOp()); arbiter = amsel.arbiterIndex(); int msel = amsel.getMselValue(); mask |= (1 << msel); @@ -678,7 +678,7 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { int slot = 0; Block &block = connectOp.getRules().front(); for (auto slotOp : block.getOps()) { - AMSelOp amselOp = dyn_cast(slotOp.getAmsel().getDefiningOp()); + AMSelOp amselOp = cast(slotOp.getAmsel().getDefiningOp()); int arbiter = amselOp.arbiterIndex(); int msel = amselOp.getMselValue(); output << "__mlir_aie_try(XAie_StrmPktSwSlavePortEnable(" @@ -770,7 +770,7 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { //--------------------------------------------------------------------------- output << "int mlir_aie_configure_cascade(" << ctx_p << ") {\n"; for (auto configOp : targetOp.getOps()) { - TileOp tile = dyn_cast(configOp.getTile().getDefiningOp()); + TileOp tile = cast(configOp.getTile().getDefiningOp()); int col = tile.colIndex(); int row = tile.rowIndex(); output << "XAie_CoreConfigAccumulatorControl(" << deviceInstRef << ", " From 5908d8a81bb20ba3c19db3d0b42321095f67087b Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 6 Feb 2024 10:08:38 -0700 Subject: [PATCH 09/51] Restructure AIEAttr.td --- include/aie/Dialect/AIE/IR/AIEAttrs.td | 41 +++++++++++++------------- lib/Targets/AIETargetCDODirect.cpp | 15 ++-------- 2 files changed, 23 insertions(+), 33 deletions(-) diff --git a/include/aie/Dialect/AIE/IR/AIEAttrs.td b/include/aie/Dialect/AIE/IR/AIEAttrs.td index c4b7a4e9ed..4d2f17371f 100644 --- a/include/aie/Dialect/AIE/IR/AIEAttrs.td +++ b/include/aie/Dialect/AIE/IR/AIEAttrs.td @@ -39,19 +39,29 @@ def AIEI64Attr : AIETypedSignlessIntegerAttrBase< // 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 WireBundle: I32EnumAttr<"WireBundle", "Bundle of wires", [ - I32EnumAttrCase<"Core", 0>, - I32EnumAttrCase<"DMA", 1>, - I32EnumAttrCase<"FIFO", 2>, - I32EnumAttrCase<"South", 3>, - I32EnumAttrCase<"West", 4>, - I32EnumAttrCase<"North", 5>, - I32EnumAttrCase<"East", 6>, - I32EnumAttrCase<"PLIO", 7>, - I32EnumAttrCase<"NOC", 8>, - I32EnumAttrCase<"Trace", 9> + CoreWire, DMAWire, FIFOWire, SouthWire, WestWire, NorthWire, + EastWire, PLIOWire, NOCWire, TraceWire + ]> { + + let cppNamespace = "xilinx::AIE"; +} + +def CascadeDir: I32EnumAttr<"CascadeDir", "Directions for cascade", + [ + SouthWire, WestWire, NorthWire, EastWire ]> { let cppNamespace = "xilinx::AIE"; @@ -144,15 +154,4 @@ def BDDimLayoutArrayArrayAttr : ArrayOfAttr< /*eltName*/BDDimLayoutArrayAttr.cppClassName >; -def CascadeDir: I32EnumAttr<"CascadeDir", "Directions for cascade", - [ - I32EnumAttrCase<"South", 0>, - I32EnumAttrCase<"West", 1>, - I32EnumAttrCase<"North", 2>, - I32EnumAttrCase<"East", 3> - ]> { - - let cppNamespace = "xilinx::AIE"; -} - #endif // AIE_ATTRS \ No newline at end of file diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index fc3d951197..e2a92535e5 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -108,14 +108,6 @@ static const std::map {WireBundle::Trace, StrmSwPortType::TRACE}, }; -static const std::map - CASCADE_DIR_TO_STRM_SW_PORT_TYPE = { - {CascadeDir::South, StrmSwPortType::SOUTH}, - {CascadeDir::West, StrmSwPortType::WEST}, - {CascadeDir::North, StrmSwPortType::NORTH}, - {CascadeDir::East, StrmSwPortType::EAST}, -}; - // https://stackoverflow.com/a/32230306 template @@ -656,8 +648,7 @@ struct AIEControl { int slot = 0; Block &block = connectOp.getRules().front(); for (auto slotOp : block.getOps()) { - AMSelOp amselOp = - cast(slotOp.getAmsel().getDefiningOp()); + AMSelOp amselOp = cast(slotOp.getAmsel().getDefiningOp()); int arbiter = amselOp.arbiterIndex(); int msel = amselOp.getMselValue(); TRY_XAIE_API_EMIT_ERROR( @@ -712,8 +703,8 @@ struct AIEControl { auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); TRY_XAIE_API_EMIT_ERROR( targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, - CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getInputDir()), - CASCADE_DIR_TO_STRM_SW_PORT_TYPE.at(configOp.getOutputDir())); + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getInputDir())), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getOutputDir()))); } return success(); From d263910916e872a43ae23452cc96739c94b77c8b Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 6 Feb 2024 11:39:16 -0700 Subject: [PATCH 10/51] Modify CDO and Airbin targets. --- lib/Targets/AIETargetAirbin.cpp | 28 ++++++++++++++++++++++++++++ lib/Targets/AIETargetCDODirect.cpp | 17 ++++++++++------- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index f0fa86fdc4..675330f7db 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1061,6 +1061,33 @@ static void configureSwitchBoxes(DeviceOp &targetOp) { */ } +static void configureCascade(DeviceOp &targetOp) { + const auto &target_model = xilinx::AIE::getTargetModel(targetOp); + if (target_model.getTargetArch() == AIEArch::AIE2) { + for (auto configOp : targetOp.getOps()) { + TileOp tile = cast(configOp.getTile().getDefiningOp()); + auto inputDir = stringifyCascadeDir(configOp.getInputDir()).upper(); + auto outputDir = stringifyCascadeDir(configOp.getOutputDir()).upper(); + + Address address{tile, 0x36060u}; + + /* + * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST + * * Register value for input BIT 0: 0 == NORTH, 1 == WEST + */ + uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; + uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; + + constexpr Field<1> Output; + constexpr Field<0> Input; + + auto regValue = Output(outputValue) | Input(inputValue); + + write32(address, regValue); + } + } +} + /* Convert memory address to index @@ -1184,6 +1211,7 @@ mlir::LogicalResult AIETranslateToAirbin(mlir::ModuleOp module, } configureSwitchBoxes(targetOp); + configureCascade(targetOp); configureDMAs(targetOp); groupSections(sections); diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index e2a92535e5..6eb912610c 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -698,13 +698,16 @@ struct AIEControl { } // Cascade configuration - for (auto configOp : targetOp.getOps()) { - TileOp tile = cast(configOp.getTile().getDefiningOp()); - auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); - TRY_XAIE_API_EMIT_ERROR( - targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getInputDir())), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getOutputDir()))); + const auto &target_model = xilinx::AIE::getTargetModel(targetOp); + if (target_model.getTargetArch() == AIEArch::AIE2) { + for (auto configOp : targetOp.getOps()) { + TileOp tile = cast(configOp.getTile().getDefiningOp()); + auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); + TRY_XAIE_API_EMIT_ERROR( + targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getInputDir())), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getOutputDir()))); + } } return success(); From d06465ef8c78f35099a2efe352877d2334b3acc3 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 6 Feb 2024 10:41:44 -0800 Subject: [PATCH 11/51] Update lib/Targets/AIETargetAirbin.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Targets/AIETargetAirbin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index 675330f7db..6c78a00ed3 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1072,9 +1072,9 @@ static void configureCascade(DeviceOp &targetOp) { Address address{tile, 0x36060u}; /* - * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST - * * Register value for input BIT 0: 0 == NORTH, 1 == WEST - */ + * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST + * * Register value for input BIT 0: 0 == NORTH, 1 == WEST + */ uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; From 20267f99a2ac38ecfc1b174530abe68fab36c76e Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 6 Feb 2024 10:41:55 -0800 Subject: [PATCH 12/51] Update lib/Targets/AIETargetCDODirect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Targets/AIETargetCDODirect.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 6eb912610c..63c34d5c9d 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -705,8 +705,10 @@ struct AIEControl { auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); TRY_XAIE_API_EMIT_ERROR( targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getInputDir())), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(static_cast(configOp.getOutputDir()))); + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + static_cast(configOp.getInputDir())), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + static_cast(configOp.getOutputDir()))); } } From 40858b05a2df9929f517b3d52d499d846a69e220 Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 6 Feb 2024 14:42:54 -0700 Subject: [PATCH 13/51] Add ipu test --- test/ipu-xrt/configure_cascade/aie.mlir | 66 ++++++++ test/ipu-xrt/configure_cascade/kernel1.cc | 28 ++++ test/ipu-xrt/configure_cascade/kernel2.cc | 27 +++ test/ipu-xrt/configure_cascade/run.lit | 14 ++ test/ipu-xrt/configure_cascade/test.cpp | 192 ++++++++++++++++++++++ 5 files changed, 327 insertions(+) create mode 100644 test/ipu-xrt/configure_cascade/aie.mlir create mode 100755 test/ipu-xrt/configure_cascade/kernel1.cc create mode 100755 test/ipu-xrt/configure_cascade/kernel2.cc create mode 100644 test/ipu-xrt/configure_cascade/run.lit create mode 100644 test/ipu-xrt/configure_cascade/test.cpp diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir new file mode 100644 index 0000000000..2e86aaac44 --- /dev/null +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -0,0 +1,66 @@ +//===- aie.mlir ------------------------------------------------*- MLIR -*-===// +// +// Copyright (C) 2024, Advanced Micro Devices, Inc. +// SPDX-License-Identifier: MIT +// +//===----------------------------------------------------------------------===// + +module { + aie.device(ipu) { + %t00 = aie.tile(0, 0) + %t01 = aie.tile(0, 1) + %t02 = aie.tile(0, 2) + %t12 = aie.tile(1, 2) + + aie.configure_cascade(%t02, West, East) + aie.configure_cascade(%t12, West, East) + + aie.objectfifo @objFifo_in0(%t00, {%t01}, 1 : i32) : !aie.objectfifo> + aie.objectfifo @objFifo_in1(%t01, {%t02}, 1 : i32) : !aie.objectfifo> + aie.objectfifo.link [@objFifo_in0] -> [@objFifo_in1] () + + aie.objectfifo @objFifo_out1(%t12, {%t01}, 1 : i32) : !aie.objectfifo> + aie.objectfifo @objFifo_out0(%t01, {%t00}, 1 : i32) : !aie.objectfifo> + aie.objectfifo.link [@objFifo_out1] -> [@objFifo_out0] () + + func.func private @extern_kernel1() -> () + func.func private @extern_kernel2(%b: memref<64xi32>) -> () + + %lock13_1 = aie.lock(%t02, 1) { sym_name = "lock_13_1" } + + %core02 = aie.core(%t02) { + %subview0 = aie.objectfifo.acquire @objFifo_in1(Consume, 1) : !aie.objectfifosubview> + aie.use_lock(%lock13_1, "Acquire", 0) + + func.call @extern_kernel1() : () -> () + + aie.use_lock(%lock13_1, "Release", 1) + aie.objectfifo.release @objFifo_in1(Consume, 1) + + aie.end + } { link_with="kernel1.o" } + + %core12 = aie.core(%t12) { + aie.use_lock(%lock13_1, "Acquire", 1) + + %subview1 = aie.objectfifo.acquire @objFifo_out1(Produce, 1) : !aie.objectfifosubview> + %elem1 = aie.objectfifo.subview.access %subview1[0] : !aie.objectfifosubview> -> memref<64xi32> + + func.call @extern_kernel2(%elem1) : (memref<64xi32>) -> () + + aie.use_lock(%lock13_1, "Release", 0) + aie.objectfifo.release @objFifo_out1(Produce, 1) + aie.end + } { link_with="kernel2.o" } + + func.func @sequence(%in : memref<64xi32>, %buf : memref<32xi32>, %out : memref<64xi32>) { + %c0 = arith.constant 0 : i64 + %c1 = arith.constant 1 : i64 + %c64 = arith.constant 64 : i64 + aiex.ipu.dma_memcpy_nd (0, 0, %out[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c64][%c0,%c0,%c0]) { metadata = @objFifo_out0, id = 1 : i64 } : memref<64xi32> + aiex.ipu.dma_memcpy_nd (0, 0, %in[%c0,%c0,%c0,%c0][%c1,%c1,%c1,%c64][%c0,%c0,%c0]) { metadata = @objFifo_in0, id = 0 : i64 } : memref<64xi32> + aiex.ipu.sync { column = 0 : i32, row = 0 : i32, direction = 0 : i32, channel = 0 : i32, column_num = 1 : i32, row_num = 1 : i32 } + return + } + } +} diff --git a/test/ipu-xrt/configure_cascade/kernel1.cc b/test/ipu-xrt/configure_cascade/kernel1.cc new file mode 100755 index 0000000000..3f3adb44c5 --- /dev/null +++ b/test/ipu-xrt/configure_cascade/kernel1.cc @@ -0,0 +1,28 @@ +//===- kernel1.cc -------------------------------------------------*- 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 +// +// Copyright (C) 2024, Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#define __AIENGINE__ 2 +#define NOCPP +#define __AIEARCH__ 20 + +#include +#include +#include + +extern "C" { + +void extern_kernel1() { + v32int32 v32 = undef_v32int32(); + v32 = upd_elem(v32, 0, 14); + put_mcd(v32); +} + +} // extern "C" \ No newline at end of file diff --git a/test/ipu-xrt/configure_cascade/kernel2.cc b/test/ipu-xrt/configure_cascade/kernel2.cc new file mode 100755 index 0000000000..615051c27d --- /dev/null +++ b/test/ipu-xrt/configure_cascade/kernel2.cc @@ -0,0 +1,27 @@ +//===- kernel2.cc -------------------------------------------------*- 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 +// +// Copyright (C) 2024, Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#define __AIENGINE__ 2 +#define NOCPP +#define __AIEARCH__ 20 + +#include +#include +#include + +extern "C" { + +void extern_kernel2(int32_t *restrict buf) { + v32int32 v32 = get_scd_v32int32(); + buf[5] = ext_elem(v32, 0) + 100; +} + +} // extern "C" \ No newline at end of file diff --git a/test/ipu-xrt/configure_cascade/run.lit b/test/ipu-xrt/configure_cascade/run.lit new file mode 100644 index 0000000000..93ac5d9bba --- /dev/null +++ b/test/ipu-xrt/configure_cascade/run.lit @@ -0,0 +1,14 @@ +// (c) Copyright 2024 Advanced Micro Devices, Inc. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +// REQUIRES: ryzen_ai +// +// RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel1.cc -o ./kernel1.o +// RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel2.cc -o ./kernel2.o +// RUN: %python aiecc.py --no-aiesim --aie-generate-cdo --aie-generate-ipu --no-compile-host --xclbin-name=aie.xclbin --ipu-insts-name=insts.txt %S/aie.mlir +// RUN: cp *.elf aie.mlir.prj/ +// RUN: cp *.bin aie.mlir.prj/ +// RUN: %python aiecc.py --no-aiesim --aie-generate-ipu --aie-generate-xclbin --no-compile-host --xclbin-name=aie.xclbin --ipu-insts-name=insts.txt %S/aie.mlir +// RUN: clang %S/test.cpp -o test.exe -std=c++11 -Wall %xrt_flags -lrt -lstdc++ -lboost_program_options -lboost_filesystem +// RUN: %run_on_ipu ./test.exe -x aie.xclbin -k MLIR_AIE -i insts.txt | FileCheck %s +// CHECK: PASS! diff --git a/test/ipu-xrt/configure_cascade/test.cpp b/test/ipu-xrt/configure_cascade/test.cpp new file mode 100644 index 0000000000..f39953147e --- /dev/null +++ b/test/ipu-xrt/configure_cascade/test.cpp @@ -0,0 +1,192 @@ +//===- test.cpp -------------------------------------------000---*- 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 +// +// Copyright (C) 2024, Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#include +#include +#include +#include +#include +#include +#include + +#include "xrt/xrt_bo.h" +#include "xrt/xrt_device.h" +#include "xrt/xrt_kernel.h" + +constexpr int IN_SIZE = 64; +constexpr int OUT_SIZE = 64; + +namespace po = boost::program_options; + +void check_arg_file_exists(po::variables_map &vm_in, std::string name) { + if (!vm_in.count(name)) { + throw std::runtime_error("Error: no " + name + " file was provided\n"); + } else { + std::ifstream test(vm_in[name].as()); + if (!test) { + throw std::runtime_error("The " + name + " file " + + vm_in[name].as() + + " does not exist.\n"); + } + } +} + +std::vector load_instr_sequence(std::string instr_path) { + std::ifstream instr_file(instr_path); + std::string line; + std::vector instr_v; + while (std::getline(instr_file, line)) { + std::istringstream iss(line); + uint32_t a; + if (!(iss >> std::hex >> a)) { + throw std::runtime_error("Unable to parse instruction file\n"); + } + instr_v.push_back(a); + } + return instr_v; +} + +int main(int argc, const char *argv[]) { + + // Program arguments parsing + po::options_description desc("Allowed options"); + desc.add_options()("help,h", "produce help message")( + "xclbin,x", po::value()->required(), + "the input xclbin path")( + "kernel,k", po::value()->required(), + "the kernel name in the XCLBIN (for instance PP_PRE_FD)")( + "verbosity,v", po::value()->default_value(0), + "the verbosity of the output")( + "instr,i", po::value()->required(), + "path of file containing userspace instructions to be sent to the LX6"); + po::variables_map vm; + + try { + po::store(po::parse_command_line(argc, argv, desc), vm); + po::notify(vm); + + if (vm.count("help")) { + std::cout << desc << "\n"; + return 1; + } + } catch (const std::exception &ex) { + std::cerr << ex.what() << "\n\n"; + std::cerr << "Usage:\n" << desc << "\n"; + return 1; + } + + check_arg_file_exists(vm, "xclbin"); + check_arg_file_exists(vm, "instr"); + + std::vector instr_v = + load_instr_sequence(vm["instr"].as()); + + int verbosity = vm["verbosity"].as(); + if (verbosity >= 1) + std::cout << "Sequence instr count: " << instr_v.size() << "\n"; + + // Start the XRT test code + // Get a device handle + unsigned int device_index = 0; + auto device = xrt::device(device_index); + + // Load the xclbin + if (verbosity >= 1) + std::cout << "Loading xclbin: " << vm["xclbin"].as() << "\n"; + auto xclbin = xrt::xclbin(vm["xclbin"].as()); + + if (verbosity >= 1) + std::cout << "Kernel opcode: " << vm["kernel"].as() << "\n"; + std::string Node = vm["kernel"].as(); + + // Get the kernel from the xclbin + auto xkernels = xclbin.get_kernels(); + auto xkernel = *std::find_if(xkernels.begin(), xkernels.end(), + [Node](xrt::xclbin::kernel &k) { + auto name = k.get_name(); + std::cout << "Name: " << name << std::endl; + return name.rfind(Node, 0) == 0; + }); + auto kernelName = xkernel.get_name(); + + if (verbosity >= 1) + std::cout << "Registering xclbin: " << vm["xclbin"].as() + << "\n"; + + device.register_xclbin(xclbin); + + // get a hardware context + if (verbosity >= 1) + std::cout << "Getting hardware context.\n"; + xrt::hw_context context(device, xclbin.get_uuid()); + + // get a kernel handle + if (verbosity >= 1) + std::cout << "Getting handle to kernel:" << kernelName << "\n"; + auto kernel = xrt::kernel(context, kernelName); + + auto bo_instr = xrt::bo(device, instr_v.size() * sizeof(int), + XCL_BO_FLAGS_CACHEABLE, kernel.group_id(0)); + auto bo_inA = xrt::bo(device, IN_SIZE * sizeof(int32_t), + XRT_BO_FLAGS_HOST_ONLY, kernel.group_id(2)); + auto bo_inB = xrt::bo(device, IN_SIZE * sizeof(int32_t), + XRT_BO_FLAGS_HOST_ONLY, kernel.group_id(3)); + auto bo_out = xrt::bo(device, OUT_SIZE * sizeof(int32_t), + XRT_BO_FLAGS_HOST_ONLY, kernel.group_id(4)); + + if (verbosity >= 1) + std::cout << "Writing data into buffer objects.\n"; + + uint32_t *bufInA = bo_inA.map(); + std::vector srcVecA; + for (int i = 0; i < IN_SIZE; i++) + srcVecA.push_back(i + 1); + memcpy(bufInA, srcVecA.data(), (srcVecA.size() * sizeof(uint32_t))); + + void *bufInstr = bo_instr.map(); + memcpy(bufInstr, instr_v.data(), instr_v.size() * sizeof(int)); + + bo_instr.sync(XCL_BO_SYNC_BO_TO_DEVICE); + bo_inA.sync(XCL_BO_SYNC_BO_TO_DEVICE); + + if (verbosity >= 1) + std::cout << "Running Kernel.\n"; + auto run = kernel(bo_instr, instr_v.size(), bo_inA, bo_inB, bo_out); + run.wait(); + + bo_out.sync(XCL_BO_SYNC_BO_FROM_DEVICE); + + uint32_t *bufOut = bo_out.map(); + + int errors = 0; + + for (uint32_t i = 0; i < 64; i++) { + uint32_t ref = 0; + if (i == 5) { + ref = 114; + } + if (*(bufOut + i) != ref) { + std::cout << "Error in output " << *(bufOut + i) << " != " << ref + << std::endl; + errors++; + } else { + std::cout << "Correct output " << *(bufOut + i) << " == " << ref + << std::endl; + } + } + + if (!errors) { + std::cout << "\nPASS!\n\n"; + return 0; + } else { + std::cout << "\nfailed.\n\n"; + return 1; + } +} From 7147c38468e2b7a11f4a81aa77886f2a1b98a97c Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 6 Feb 2024 15:59:32 -0700 Subject: [PATCH 14/51] Update test with AIE2 locks --- test/ipu-xrt/configure_cascade/aie.mlir | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir index 2e86aaac44..e4a6e02386 100644 --- a/test/ipu-xrt/configure_cascade/aie.mlir +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -26,29 +26,30 @@ module { func.func private @extern_kernel1() -> () func.func private @extern_kernel2(%b: memref<64xi32>) -> () - %lock13_1 = aie.lock(%t02, 1) { sym_name = "lock_13_1" } + %lock13_1 = aie.lock(%t02, 1) { sym_name = "lock_13_1", init = 1 : i32 } + %lock13_2 = aie.lock(%t02, 1) { sym_name = "lock_13_2" } %core02 = aie.core(%t02) { %subview0 = aie.objectfifo.acquire @objFifo_in1(Consume, 1) : !aie.objectfifosubview> - aie.use_lock(%lock13_1, "Acquire", 0) + aie.use_lock(%lock13_1, "AcquireGreaterEqual", 1) func.call @extern_kernel1() : () -> () - aie.use_lock(%lock13_1, "Release", 1) + aie.use_lock(%lock13_2, "Release", 1) aie.objectfifo.release @objFifo_in1(Consume, 1) aie.end } { link_with="kernel1.o" } %core12 = aie.core(%t12) { - aie.use_lock(%lock13_1, "Acquire", 1) + aie.use_lock(%lock13_2, "AcquireGreaterEqual", 1) %subview1 = aie.objectfifo.acquire @objFifo_out1(Produce, 1) : !aie.objectfifosubview> %elem1 = aie.objectfifo.subview.access %subview1[0] : !aie.objectfifosubview> -> memref<64xi32> func.call @extern_kernel2(%elem1) : (memref<64xi32>) -> () - aie.use_lock(%lock13_1, "Release", 0) + aie.use_lock(%lock13_1, "Release", 1) aie.objectfifo.release @objFifo_out1(Produce, 1) aie.end } { link_with="kernel2.o" } From 29376c785acc0c89633d2e8b62c639a984e98753 Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 7 Feb 2024 09:16:20 -0700 Subject: [PATCH 15/51] Fix lock value --- test/ipu-xrt/configure_cascade/aie.mlir | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir index e4a6e02386..bb9c350ab3 100644 --- a/test/ipu-xrt/configure_cascade/aie.mlir +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -27,7 +27,7 @@ module { func.func private @extern_kernel2(%b: memref<64xi32>) -> () %lock13_1 = aie.lock(%t02, 1) { sym_name = "lock_13_1", init = 1 : i32 } - %lock13_2 = aie.lock(%t02, 1) { sym_name = "lock_13_2" } + %lock13_2 = aie.lock(%t02, 2) { sym_name = "lock_13_2" } %core02 = aie.core(%t02) { %subview0 = aie.objectfifo.acquire @objFifo_in1(Consume, 1) : !aie.objectfifosubview> From 4c9fffae846828477fa3dedd90501351ce42fa66 Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 7 Feb 2024 17:23:12 -0700 Subject: [PATCH 16/51] Add Makefile to configure_cascade test --- test/ipu-xrt/configure_cascade/Makefile | 39 +++++++++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 test/ipu-xrt/configure_cascade/Makefile diff --git a/test/ipu-xrt/configure_cascade/Makefile b/test/ipu-xrt/configure_cascade/Makefile new file mode 100644 index 0000000000..f2689d304f --- /dev/null +++ b/test/ipu-xrt/configure_cascade/Makefile @@ -0,0 +1,39 @@ +##===- Makefile -----------------------------------------------------------===## +# +# This file 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 ../makefile-common + +targetname = configureCascade + +all: build/final.xclbin build/insts.txt + +build/%.o: %.cc + mkdir -p ${@D} + cd ${@D} && xchesscc_wrapper ${CHESSCCWRAP2_FLAGS} -DBIT_WIDTH=8 -c $(<:%=../%) -o ${@F} + +build/final.xclbin: aie.mlir build/kernel1.o build/kernel2.o + mkdir -p ${@D} + cd ${@D} && aiecc.py --aie-generate-cdo --no-compile-host --xclbin-name=${@F} \ + --aie-generate-ipu --ipu-insts-name=insts.txt $(<:%=../%) + +${targetname}.exe: test.cpp + rm -rf _build + mkdir -p _build + cd _build && ${powershell} cmake .. -DTARGET_NAME=${targetname} + cd _build && ${powershell} cmake --build . --config Release +ifeq "${powershell}" "powershell.exe" + cp _build/${targetname}.exe $@ +else + cp _build/${targetname} $@ +endif + +run: ${targetname}.exe build/final.xclbin build/insts.txt + ${powershell} ./$< -x build/final.xclbin -i build/insts.txt -k MLIR_AIE + +clean: + rm -rf build _build ${targetname}.exe From 842403050679017f5701fd68c8b0b2817feca1ba Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 7 Feb 2024 17:29:05 -0700 Subject: [PATCH 17/51] Add CMakeLists to configure_cascade --- test/ipu-xrt/configure_cascade/CMakeLists.txt | 68 +++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 test/ipu-xrt/configure_cascade/CMakeLists.txt diff --git a/test/ipu-xrt/configure_cascade/CMakeLists.txt b/test/ipu-xrt/configure_cascade/CMakeLists.txt new file mode 100644 index 0000000000..257e7ca075 --- /dev/null +++ b/test/ipu-xrt/configure_cascade/CMakeLists.txt @@ -0,0 +1,68 @@ +# 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 2024 Advanced Micro Devices, Inc. + +# parameters +# -DBOOST_ROOT: Path to Boost install +# -DXRT_INC_DIR: Full path to src/runtime_src/core/include in XRT cloned repo +# -DXRT_LIB_DIR: Path to xrt_coreutil.lib +# -DTARGET_NAME: Target name to be built + +# cmake needs this line +cmake_minimum_required(VERSION 3.1) + +find_program(WSL NAMES powershell.exe) + +if (NOT WSL) + set(BOOST_ROOT /usr/include/boost CACHE STRING "Path to Boost install") + set(XRT_INC_DIR /opt/xilinx/xrt/include CACHE STRING "Path to XRT cloned repo") + set(XRT_LIB_DIR /opt/xilinx/xrt/lib CACHE STRING "Path to xrt_coreutil.lib") +else() + set(BOOST_ROOT C:/Technical/thirdParty/boost_1_83_0 CACHE STRING "Path to Boost install") + set(XRT_INC_DIR C:/Technical/XRT/src/runtime_src/core/include CACHE STRING "Path to XRT cloned repo") + set(XRT_LIB_DIR C:/Technical/xrtIPUfromDLL CACHE STRING "Path to xrt_coreutil.lib") +endif() + +set(TARGET_NAME test CACHE STRING "Target to be built") + +SET (ProjectName ${TARGET_NAME}) +SET (currentTarget ${TARGET_NAME}) + +if ( WSL ) + set(CMAKE_RUNTIME_OUTPUT_DIRECTORY_RELEASE ${CMAKE_BINARY_DIR}) +endif () + +project(${ProjectName}) + +# Find packages +find_package(Boost REQUIRED) + +add_executable(${currentTarget} + test.cpp +) + +target_compile_definitions(${currentTarget} PUBLIC DISABLE_ABI_CHECK=1) + +target_include_directories (${currentTarget} PUBLIC + ${XRT_INC_DIR} + ${Boost_INCLUDE_DIRS} +) + +target_link_directories(${currentTarget} PUBLIC + ${XRT_LIB_DIR} + ${Boost_LIBRARY_DIRS} +) + +if (NOT WSL) + target_link_libraries(${currentTarget} PUBLIC + xrt_coreutil + boost_program_options + boost_filesystem + ) +else() + target_link_libraries(${currentTarget} PUBLIC + xrt_coreutil + ) +endif() From 717ee26c509902aaa1751753a0439b672b0d480f Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 8 Feb 2024 10:51:24 -0700 Subject: [PATCH 18/51] Make cascade ipu test more complex --- test/ipu-xrt/configure_cascade/Makefile | 2 +- test/ipu-xrt/configure_cascade/aie.mlir | 41 ++++++++++++++++------- test/ipu-xrt/configure_cascade/kernel1.cc | 8 ++++- test/ipu-xrt/configure_cascade/kernel2.cc | 5 +-- test/ipu-xrt/configure_cascade/kernel3.cc | 27 +++++++++++++++ test/ipu-xrt/configure_cascade/run.lit | 1 + 6 files changed, 68 insertions(+), 16 deletions(-) create mode 100755 test/ipu-xrt/configure_cascade/kernel3.cc diff --git a/test/ipu-xrt/configure_cascade/Makefile b/test/ipu-xrt/configure_cascade/Makefile index f2689d304f..e7cebe90a1 100644 --- a/test/ipu-xrt/configure_cascade/Makefile +++ b/test/ipu-xrt/configure_cascade/Makefile @@ -16,7 +16,7 @@ build/%.o: %.cc mkdir -p ${@D} cd ${@D} && xchesscc_wrapper ${CHESSCCWRAP2_FLAGS} -DBIT_WIDTH=8 -c $(<:%=../%) -o ${@F} -build/final.xclbin: aie.mlir build/kernel1.o build/kernel2.o +build/final.xclbin: aie.mlir build/kernel1.o build/kernel2.o build/kernel3.o mkdir -p ${@D} cd ${@D} && aiecc.py --aie-generate-cdo --no-compile-host --xclbin-name=${@F} \ --aie-generate-ipu --ipu-insts-name=insts.txt $(<:%=../%) diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir index bb9c350ab3..e9d17767f2 100644 --- a/test/ipu-xrt/configure_cascade/aie.mlir +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -9,14 +9,16 @@ module { aie.device(ipu) { %t00 = aie.tile(0, 0) %t01 = aie.tile(0, 1) - %t02 = aie.tile(0, 2) + %t03 = aie.tile(0, 3) + %t13 = aie.tile(1, 3) %t12 = aie.tile(1, 2) - aie.configure_cascade(%t02, West, East) - aie.configure_cascade(%t12, West, East) + aie.configure_cascade(%t03, West, East) + aie.configure_cascade(%t13, West, South) + aie.configure_cascade(%t12, North, South) aie.objectfifo @objFifo_in0(%t00, {%t01}, 1 : i32) : !aie.objectfifo> - aie.objectfifo @objFifo_in1(%t01, {%t02}, 1 : i32) : !aie.objectfifo> + aie.objectfifo @objFifo_in1(%t01, {%t03}, 1 : i32) : !aie.objectfifo> aie.objectfifo.link [@objFifo_in0] -> [@objFifo_in1] () aie.objectfifo @objFifo_out1(%t12, {%t01}, 1 : i32) : !aie.objectfifo> @@ -24,35 +26,50 @@ module { aie.objectfifo.link [@objFifo_out1] -> [@objFifo_out0] () func.func private @extern_kernel1() -> () - func.func private @extern_kernel2(%b: memref<64xi32>) -> () + func.func private @extern_kernel2() -> () + func.func private @extern_kernel3(%b: memref<64xi32>) -> () - %lock13_1 = aie.lock(%t02, 1) { sym_name = "lock_13_1", init = 1 : i32 } - %lock13_2 = aie.lock(%t02, 2) { sym_name = "lock_13_2" } + %lock03_1 = aie.lock(%t03, 1) { sym_name = "lock_03_1", init = 1 : i32 } + %lock03_2 = aie.lock(%t03, 2) { sym_name = "lock_03_2" } + + %lock13_1 = aie.lock(%t13, 1) { sym_name = "lock_13_1", init = 1 : i32 } + %lock13_2 = aie.lock(%t13, 2) { sym_name = "lock_13_2" } - %core02 = aie.core(%t02) { + %core02 = aie.core(%t03) { %subview0 = aie.objectfifo.acquire @objFifo_in1(Consume, 1) : !aie.objectfifosubview> - aie.use_lock(%lock13_1, "AcquireGreaterEqual", 1) + aie.use_lock(%lock03_1, "AcquireGreaterEqual", 1) func.call @extern_kernel1() : () -> () - aie.use_lock(%lock13_2, "Release", 1) + aie.use_lock(%lock03_2, "Release", 1) aie.objectfifo.release @objFifo_in1(Consume, 1) aie.end } { link_with="kernel1.o" } + %core13 = aie.core(%t13) { + aie.use_lock(%lock03_2, "AcquireGreaterEqual", 1) + aie.use_lock(%lock13_1, "AcquireGreaterEqual", 1) + + func.call @extern_kernel2() : () -> () + + aie.use_lock(%lock13_2, "Release", 1) + aie.use_lock(%lock03_1, "Release", 1) + aie.end + } { link_with="kernel2.o" } + %core12 = aie.core(%t12) { aie.use_lock(%lock13_2, "AcquireGreaterEqual", 1) %subview1 = aie.objectfifo.acquire @objFifo_out1(Produce, 1) : !aie.objectfifosubview> %elem1 = aie.objectfifo.subview.access %subview1[0] : !aie.objectfifosubview> -> memref<64xi32> - func.call @extern_kernel2(%elem1) : (memref<64xi32>) -> () + func.call @extern_kernel3(%elem1) : (memref<64xi32>) -> () aie.use_lock(%lock13_1, "Release", 1) aie.objectfifo.release @objFifo_out1(Produce, 1) aie.end - } { link_with="kernel2.o" } + } { link_with="kernel3.o" } func.func @sequence(%in : memref<64xi32>, %buf : memref<32xi32>, %out : memref<64xi32>) { %c0 = arith.constant 0 : i64 diff --git a/test/ipu-xrt/configure_cascade/kernel1.cc b/test/ipu-xrt/configure_cascade/kernel1.cc index 3f3adb44c5..800f93f4a8 100755 --- a/test/ipu-xrt/configure_cascade/kernel1.cc +++ b/test/ipu-xrt/configure_cascade/kernel1.cc @@ -21,7 +21,13 @@ extern "C" { void extern_kernel1() { v32int32 v32 = undef_v32int32(); - v32 = upd_elem(v32, 0, 14); + for (i = 0; i < 5; i++) { + if (i == 0 ) { + v32 = upd_elem(v32, i, 14); + } else { + v32 = upd_elem(v32, i, 0); + } + } put_mcd(v32); } diff --git a/test/ipu-xrt/configure_cascade/kernel2.cc b/test/ipu-xrt/configure_cascade/kernel2.cc index 615051c27d..efd0373d4a 100755 --- a/test/ipu-xrt/configure_cascade/kernel2.cc +++ b/test/ipu-xrt/configure_cascade/kernel2.cc @@ -19,9 +19,10 @@ extern "C" { -void extern_kernel2(int32_t *restrict buf) { +void extern_kernel2() { v32int32 v32 = get_scd_v32int32(); - buf[5] = ext_elem(v32, 0) + 100; + v32 = upd_elem(v32, 0, 114); + put_mcd(v32); } } // extern "C" \ No newline at end of file diff --git a/test/ipu-xrt/configure_cascade/kernel3.cc b/test/ipu-xrt/configure_cascade/kernel3.cc new file mode 100755 index 0000000000..a9646af273 --- /dev/null +++ b/test/ipu-xrt/configure_cascade/kernel3.cc @@ -0,0 +1,27 @@ +//===- kernel3.cc -------------------------------------------------*- 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 +// +// Copyright (C) 2024, Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +#define __AIENGINE__ 2 +#define NOCPP +#define __AIEARCH__ 20 + +#include +#include +#include + +extern "C" { + +void extern_kernel3(int32_t *restrict buf) { + v32int32 v32 = get_scd_v32int32(); + buf[5] = ext_elem(v32, 0) + 100; +} + +} // extern "C" \ No newline at end of file diff --git a/test/ipu-xrt/configure_cascade/run.lit b/test/ipu-xrt/configure_cascade/run.lit index 93ac5d9bba..fdcf5e0cb1 100644 --- a/test/ipu-xrt/configure_cascade/run.lit +++ b/test/ipu-xrt/configure_cascade/run.lit @@ -5,6 +5,7 @@ // // RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel1.cc -o ./kernel1.o // RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel2.cc -o ./kernel2.o +// RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel3.cc -o ./kernel3.o // RUN: %python aiecc.py --no-aiesim --aie-generate-cdo --aie-generate-ipu --no-compile-host --xclbin-name=aie.xclbin --ipu-insts-name=insts.txt %S/aie.mlir // RUN: cp *.elf aie.mlir.prj/ // RUN: cp *.bin aie.mlir.prj/ From df5e66819c8ac7ca7fa2af216859cafa155220f2 Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 8 Feb 2024 11:50:49 -0700 Subject: [PATCH 19/51] cleanup design --- test/ipu-xrt/configure_cascade/aie.mlir | 30 ++++++++++++----------- test/ipu-xrt/configure_cascade/kernel1.cc | 8 +----- test/ipu-xrt/configure_cascade/kernel3.cc | 10 ++++++-- test/ipu-xrt/configure_cascade/test.cpp | 6 ++--- 4 files changed, 28 insertions(+), 26 deletions(-) diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir index e9d17767f2..688eea99e1 100644 --- a/test/ipu-xrt/configure_cascade/aie.mlir +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -27,7 +27,7 @@ module { func.func private @extern_kernel1() -> () func.func private @extern_kernel2() -> () - func.func private @extern_kernel3(%b: memref<64xi32>) -> () + func.func private @extern_kernel3(%b: memref<64xi32>, %size: i32) -> () %lock03_1 = aie.lock(%t03, 1) { sym_name = "lock_03_1", init = 1 : i32 } %lock03_2 = aie.lock(%t03, 2) { sym_name = "lock_03_2" } @@ -48,27 +48,29 @@ module { } { link_with="kernel1.o" } %core13 = aie.core(%t13) { - aie.use_lock(%lock03_2, "AcquireGreaterEqual", 1) - aie.use_lock(%lock13_1, "AcquireGreaterEqual", 1) + aie.use_lock(%lock03_2, "AcquireGreaterEqual", 1) + aie.use_lock(%lock13_1, "AcquireGreaterEqual", 1) - func.call @extern_kernel2() : () -> () + func.call @extern_kernel2() : () -> () - aie.use_lock(%lock13_2, "Release", 1) - aie.use_lock(%lock03_1, "Release", 1) - aie.end + aie.use_lock(%lock13_2, "Release", 1) + aie.use_lock(%lock03_1, "Release", 1) + aie.end } { link_with="kernel2.o" } %core12 = aie.core(%t12) { - aie.use_lock(%lock13_2, "AcquireGreaterEqual", 1) + %size = arith.constant 64 : i32 + + aie.use_lock(%lock13_2, "AcquireGreaterEqual", 1) - %subview1 = aie.objectfifo.acquire @objFifo_out1(Produce, 1) : !aie.objectfifosubview> - %elem1 = aie.objectfifo.subview.access %subview1[0] : !aie.objectfifosubview> -> memref<64xi32> + %subview1 = aie.objectfifo.acquire @objFifo_out1(Produce, 1) : !aie.objectfifosubview> + %elem1 = aie.objectfifo.subview.access %subview1[0] : !aie.objectfifosubview> -> memref<64xi32> - func.call @extern_kernel3(%elem1) : (memref<64xi32>) -> () + func.call @extern_kernel3(%elem1, %size) : (memref<64xi32>, i32) -> () - aie.use_lock(%lock13_1, "Release", 1) - aie.objectfifo.release @objFifo_out1(Produce, 1) - aie.end + aie.use_lock(%lock13_1, "Release", 1) + aie.objectfifo.release @objFifo_out1(Produce, 1) + aie.end } { link_with="kernel3.o" } func.func @sequence(%in : memref<64xi32>, %buf : memref<32xi32>, %out : memref<64xi32>) { diff --git a/test/ipu-xrt/configure_cascade/kernel1.cc b/test/ipu-xrt/configure_cascade/kernel1.cc index 800f93f4a8..3f3adb44c5 100755 --- a/test/ipu-xrt/configure_cascade/kernel1.cc +++ b/test/ipu-xrt/configure_cascade/kernel1.cc @@ -21,13 +21,7 @@ extern "C" { void extern_kernel1() { v32int32 v32 = undef_v32int32(); - for (i = 0; i < 5; i++) { - if (i == 0 ) { - v32 = upd_elem(v32, i, 14); - } else { - v32 = upd_elem(v32, i, 0); - } - } + v32 = upd_elem(v32, 0, 14); put_mcd(v32); } diff --git a/test/ipu-xrt/configure_cascade/kernel3.cc b/test/ipu-xrt/configure_cascade/kernel3.cc index a9646af273..0839d8c1a5 100755 --- a/test/ipu-xrt/configure_cascade/kernel3.cc +++ b/test/ipu-xrt/configure_cascade/kernel3.cc @@ -19,9 +19,15 @@ extern "C" { -void extern_kernel3(int32_t *restrict buf) { +void extern_kernel3(int32_t *restrict buf, int N) { v32int32 v32 = get_scd_v32int32(); - buf[5] = ext_elem(v32, 0) + 100; + for (int i = 0; i < N; i++) { + if (i == 5) { + buf[i] = ext_elem(v32, 0) + 100; + } else { + buf[i] = 0; + } + } } } // extern "C" \ No newline at end of file diff --git a/test/ipu-xrt/configure_cascade/test.cpp b/test/ipu-xrt/configure_cascade/test.cpp index f39953147e..5276045e43 100644 --- a/test/ipu-xrt/configure_cascade/test.cpp +++ b/test/ipu-xrt/configure_cascade/test.cpp @@ -170,14 +170,14 @@ int main(int argc, const char *argv[]) { for (uint32_t i = 0; i < 64; i++) { uint32_t ref = 0; if (i == 5) { - ref = 114; + ref = 214; } if (*(bufOut + i) != ref) { - std::cout << "Error in output " << *(bufOut + i) << " != " << ref + std::cout << "Error in output at index " << i << ": " << *(bufOut + i) << " != " << ref << std::endl; errors++; } else { - std::cout << "Correct output " << *(bufOut + i) << " == " << ref + std::cout << "Correct output at index " << i << ": " << *(bufOut + i) << " == " << ref << std::endl; } } From cfa1b45ede0cfd6786c990c3f64174fe81db4b84 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Thu, 8 Feb 2024 13:09:35 -0800 Subject: [PATCH 20/51] Update test/ipu-xrt/configure_cascade/test.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- test/ipu-xrt/configure_cascade/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ipu-xrt/configure_cascade/test.cpp b/test/ipu-xrt/configure_cascade/test.cpp index 5276045e43..983cd137f9 100644 --- a/test/ipu-xrt/configure_cascade/test.cpp +++ b/test/ipu-xrt/configure_cascade/test.cpp @@ -173,8 +173,8 @@ int main(int argc, const char *argv[]) { ref = 214; } if (*(bufOut + i) != ref) { - std::cout << "Error in output at index " << i << ": " << *(bufOut + i) << " != " << ref - << std::endl; + std::cout << "Error in output at index " << i << ": " << *(bufOut + i) + << " != " << ref << std::endl; errors++; } else { std::cout << "Correct output at index " << i << ": " << *(bufOut + i) << " == " << ref From 9ce72137fc83ee7ffcd685ad425dfde5f44ef37c Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Thu, 8 Feb 2024 13:09:43 -0800 Subject: [PATCH 21/51] Update test/ipu-xrt/configure_cascade/test.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- test/ipu-xrt/configure_cascade/test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/ipu-xrt/configure_cascade/test.cpp b/test/ipu-xrt/configure_cascade/test.cpp index 983cd137f9..5f7567e3d0 100644 --- a/test/ipu-xrt/configure_cascade/test.cpp +++ b/test/ipu-xrt/configure_cascade/test.cpp @@ -177,8 +177,8 @@ int main(int argc, const char *argv[]) { << " != " << ref << std::endl; errors++; } else { - std::cout << "Correct output at index " << i << ": " << *(bufOut + i) << " == " << ref - << std::endl; + std::cout << "Correct output at index " << i << ": " << *(bufOut + i) + << " == " << ref << std::endl; } } From 4e6bd1e7948dddcb8b2fdd36e90387242aef09c3 Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 8 Feb 2024 14:10:08 -0700 Subject: [PATCH 22/51] Remove locks --- test/ipu-xrt/configure_cascade/aie.mlir | 18 +----------------- 1 file changed, 1 insertion(+), 17 deletions(-) diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir index 688eea99e1..f460e59f12 100644 --- a/test/ipu-xrt/configure_cascade/aie.mlir +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -28,47 +28,31 @@ module { func.func private @extern_kernel1() -> () func.func private @extern_kernel2() -> () func.func private @extern_kernel3(%b: memref<64xi32>, %size: i32) -> () - - %lock03_1 = aie.lock(%t03, 1) { sym_name = "lock_03_1", init = 1 : i32 } - %lock03_2 = aie.lock(%t03, 2) { sym_name = "lock_03_2" } - - %lock13_1 = aie.lock(%t13, 1) { sym_name = "lock_13_1", init = 1 : i32 } - %lock13_2 = aie.lock(%t13, 2) { sym_name = "lock_13_2" } %core02 = aie.core(%t03) { %subview0 = aie.objectfifo.acquire @objFifo_in1(Consume, 1) : !aie.objectfifosubview> - aie.use_lock(%lock03_1, "AcquireGreaterEqual", 1) func.call @extern_kernel1() : () -> () - aie.use_lock(%lock03_2, "Release", 1) aie.objectfifo.release @objFifo_in1(Consume, 1) aie.end } { link_with="kernel1.o" } %core13 = aie.core(%t13) { - aie.use_lock(%lock03_2, "AcquireGreaterEqual", 1) - aie.use_lock(%lock13_1, "AcquireGreaterEqual", 1) - func.call @extern_kernel2() : () -> () - aie.use_lock(%lock13_2, "Release", 1) - aie.use_lock(%lock03_1, "Release", 1) aie.end } { link_with="kernel2.o" } %core12 = aie.core(%t12) { %size = arith.constant 64 : i32 - - aie.use_lock(%lock13_2, "AcquireGreaterEqual", 1) - + %subview1 = aie.objectfifo.acquire @objFifo_out1(Produce, 1) : !aie.objectfifosubview> %elem1 = aie.objectfifo.subview.access %subview1[0] : !aie.objectfifosubview> -> memref<64xi32> func.call @extern_kernel3(%elem1, %size) : (memref<64xi32>, i32) -> () - aie.use_lock(%lock13_1, "Release", 1) aie.objectfifo.release @objFifo_out1(Produce, 1) aie.end } { link_with="kernel3.o" } From 757b761165f906dd2cdcfe447fa49129e96ede98 Mon Sep 17 00:00:00 2001 From: abisca Date: Mon, 12 Feb 2024 11:02:56 -0700 Subject: [PATCH 23/51] Fix run.lit --- test/ipu-xrt/configure_cascade/run.lit | 3 --- 1 file changed, 3 deletions(-) diff --git a/test/ipu-xrt/configure_cascade/run.lit b/test/ipu-xrt/configure_cascade/run.lit index fdcf5e0cb1..4c4b1347a1 100644 --- a/test/ipu-xrt/configure_cascade/run.lit +++ b/test/ipu-xrt/configure_cascade/run.lit @@ -7,9 +7,6 @@ // RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel2.cc -o ./kernel2.o // RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel3.cc -o ./kernel3.o // RUN: %python aiecc.py --no-aiesim --aie-generate-cdo --aie-generate-ipu --no-compile-host --xclbin-name=aie.xclbin --ipu-insts-name=insts.txt %S/aie.mlir -// RUN: cp *.elf aie.mlir.prj/ -// RUN: cp *.bin aie.mlir.prj/ -// RUN: %python aiecc.py --no-aiesim --aie-generate-ipu --aie-generate-xclbin --no-compile-host --xclbin-name=aie.xclbin --ipu-insts-name=insts.txt %S/aie.mlir // RUN: clang %S/test.cpp -o test.exe -std=c++11 -Wall %xrt_flags -lrt -lstdc++ -lboost_program_options -lboost_filesystem // RUN: %run_on_ipu ./test.exe -x aie.xclbin -k MLIR_AIE -i insts.txt | FileCheck %s // CHECK: PASS! From 697d30f63fecefc227a380d616aa304483cbc0f6 Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 13 Feb 2024 06:17:24 -0700 Subject: [PATCH 24/51] Delete ConfigureCascadeOp and replace with CascadeFlowOp and CascadeSwitchboxOp. --- include/aie/Dialect/AIE/IR/AIEAttrs.td | 8 -- include/aie/Dialect/AIE/IR/AIEOps.td | 70 ++++++++--- .../aie/Dialect/AIE/Transforms/AIEPasses.h | 2 + .../aie/Dialect/AIE/Transforms/AIEPasses.td | 13 +++ lib/Dialect/AIE/IR/AIEDialect.cpp | 82 ++++++++++--- .../AIE/Transforms/AIECoreToStandard.cpp | 3 +- .../AIE/Transforms/AIELowerCascadeFlows.cpp | 109 ++++++++++++++++++ lib/Dialect/AIE/Transforms/CMakeLists.txt | 1 + lib/Targets/AIETargetAirbin.cpp | 37 +++--- lib/Targets/AIETargetCDODirect.cpp | 23 ++-- lib/Targets/AIETargetXAIEV2.cpp | 19 ++- .../AIEGenerateXAIE/aie2_cascade_flow.mlir | 40 +++++++ test/dialect/AIE/bad_cascade.mlir | 42 +++++-- ...scade_configure.mlir => cascade_flow.mlir} | 5 +- test/ipu-xrt/configure_cascade/aie.mlir | 5 +- test/lower-cascade-flows/cascade_flow.mlir | 44 +++++++ .../aie2/03_cascade_core_functions/aie.mlir | 3 +- 17 files changed, 418 insertions(+), 88 deletions(-) create mode 100644 lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp create mode 100644 test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir rename test/dialect/AIE/{cascade_configure.mlir => cascade_flow.mlir} (75%) create mode 100644 test/lower-cascade-flows/cascade_flow.mlir diff --git a/include/aie/Dialect/AIE/IR/AIEAttrs.td b/include/aie/Dialect/AIE/IR/AIEAttrs.td index 4d2f17371f..932005919a 100644 --- a/include/aie/Dialect/AIE/IR/AIEAttrs.td +++ b/include/aie/Dialect/AIE/IR/AIEAttrs.td @@ -59,14 +59,6 @@ def WireBundle: I32EnumAttr<"WireBundle", "Bundle of wires", 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>, diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index e90e557998..ec9469ace7 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -369,7 +369,7 @@ def AIE_PLIOOp: AIE_Op<"plio", [ }]; } -def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { +def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp", "CascadeSwitchboxOp"]> ]> { let arguments = ( ins WireBundle:$sourceBundle, ConfinedAttr]>:$sourceChannel, @@ -380,7 +380,7 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> 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. + This operation must exist within an `aie.switchbox` or `aie.shim_switchbox` or `aie.cascade_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. @@ -1343,28 +1343,66 @@ def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { }]; } -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"; +def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { + let arguments = ( + ins Index:$sourceTile, + Index:$destTile + ); + let summary = "A cascade connection between tiles"; let description = [{ - An operation to configure the cascade on a single tile in both the input and the output - directions. + The `aie.cascade_flow` operation represents a cascade connection between two `aie.tile` operations. + During routing, this is replaced by `aie.connect` operations which represent the programmed connections + inside an `aie.cascade_switchbox`. Example: ``` - %tile00 = aie.tile(1, 3) - aie.configure_cascade(%tile00, West, East) + %tile03 = aie.tile(0, 3) + %tile13 = aie.tile(1, 3) + aie.cascade_flow(%tile03, %tile13) ``` - Configures the input cascade port of %tile00 to the West direction, and the output port to the East direction. }]; + let hasVerifier = 1; + let assemblyFormat = [{ + `(` $sourceTile `,` $destTile `)` attr-dict + }]; + let extraClassDeclaration = [{ + TileOp getSourceTileOp(); + TileOp getDestTileOp(); + }]; +} - let arguments = ( - ins Index:$tile, - CascadeDir:$inputDir, - CascadeDir:$outputDir - ); - let results = (outs); +def AIE_CascadeSwitchboxOp: AIE_Op<"cascade_switchbox", [ + TileElement, + SingleBlockImplicitTerminator<"EndOp">, + DeclareOpInterfaceMethods + ]>, Results<(outs Index:$result)> { + let arguments = (ins Index:$tile); + + let summary = "Declare a cascade switch"; + let description = [{ + This operation represents a switchbox which contans the programmed input and output directions + for the cascade streams on a tile. A switchbox is configured by code in its region, representing + various connections. + + Example: + ``` + %tile = aie.tile(1, 1) + aie.cascade_switchbox(%tile) { + aie.connect<"West" : 0, "East" : 0> + } + ``` + }]; + + let regions = (region AnyRegion:$connections); + let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; let hasVerifier = 1; - let assemblyFormat = [{ `(` $tile `,` $inputDir `,` $outputDir `)` attr-dict }]; + + let extraClassDeclaration = [{ + int colIndex(); + int rowIndex(); + TileOp getTileOp(); + using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; + }]; } def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascadeValue)> { diff --git a/include/aie/Dialect/AIE/Transforms/AIEPasses.h b/include/aie/Dialect/AIE/Transforms/AIEPasses.h index 38916cae7f..550f53e727 100644 --- a/include/aie/Dialect/AIE/Transforms/AIEPasses.h +++ b/include/aie/Dialect/AIE/Transforms/AIEPasses.h @@ -41,6 +41,8 @@ std::unique_ptr> createAIEObjectFifoStatefulTransformPass(); std::unique_ptr> createAIEObjectFifoRegisterProcessPass(); +std::unique_ptr> +createAIELowerCascadeFlowsPass(); /// Generate the code for registering passes. #define GEN_PASS_REGISTRATION diff --git a/include/aie/Dialect/AIE/Transforms/AIEPasses.td b/include/aie/Dialect/AIE/Transforms/AIEPasses.td index 21e1280dee..9f5a45347b 100644 --- a/include/aie/Dialect/AIE/Transforms/AIEPasses.td +++ b/include/aie/Dialect/AIE/Transforms/AIEPasses.td @@ -211,4 +211,17 @@ def AIEObjectFifoRegisterProcess : Pass<"aie-register-objectFifos", "DeviceOp"> ]; } +def AIELowerCascadeFlows : Pass<"aie-lower-cascade-flows", "DeviceOp"> { + let summary = "Lower aie.cascade_flow operations through cascade switchboxes"; + let description = [{ + Replace each aie.cascade_flow operation with an equivalent set of aie.cascade_switchbox + operations. + }]; + + let constructor = "xilinx::AIE::createAIELowerCascadeFlowsPass()"; + let dependentDialects = [ + "xilinx::AIE::AIEDialect", + ]; +} + #endif diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 2dae48dd4f..bfc06bd650 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -907,30 +907,78 @@ ObjectFifoCreateOp ObjectFifoRegisterProcessOp::getObjectFifo() { } //===----------------------------------------------------------------------===// -// ConfigureCascadeOp +// CascadeFlowOp //===----------------------------------------------------------------------===// -LogicalResult ConfigureCascadeOp::verify() { - const auto &targetModel = getTargetModel(*this); - CascadeDir inputDir = getInputDir(); - CascadeDir outputDir = getOutputDir(); - if (targetModel.getTargetArch() == AIEArch::AIE2) { - if (inputDir == CascadeDir::South || inputDir == CascadeDir::East) { - return emitOpError("input direction of cascade must be North or West on ") - << stringifyAIEArch(targetModel.getTargetArch()); - } - if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { - return emitOpError( - "output direction of cascade must be South or East on ") - << stringifyAIEArch(targetModel.getTargetArch()); +LogicalResult CascadeFlowOp::verify() { + TileOp src = getSourceTileOp(); + TileOp dst = getDestTileOp(); + const auto &t = getTargetModel(src); + 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()); +} + +//===----------------------------------------------------------------------===// +// CascadeSwitchboxOp +//===----------------------------------------------------------------------===// + +LogicalResult CascadeSwitchboxOp::verify() { + Region &body = getConnections(); + if (body.empty()) + return emitOpError("should have non-empty body"); + + int numOp = 0; + for (auto &ops : body.front()) { + if (auto connectOp = dyn_cast(ops)) { + numOp++; + WireBundle inDir = connectOp.getSourceBundle(); + if (inDir != WireBundle::West && inDir != WireBundle::North) { + return connectOp.emitOpError("source port of ConnectOp in CascadeSwitchboxOp must be West or North"); + } + WireBundle outDir = connectOp.getDestBundle(); + if (outDir != WireBundle::East && outDir != WireBundle::South) { + return connectOp.emitOpError("dest port of ConnectOp in CascadeSwitchboxOp must be East or South"); + } + if (connectOp.sourceIndex() != 0 || connectOp.destIndex() != 0) { + return connectOp.emitOpError("portIndex of ConnectOp is out-of-bounds"); + } + } else if (isa(ops)) { + // continue; + } else { + return ops.emitOpError("cannot be contained in a CascadeSwitchboxOp"); } - } else { - return emitOpError("cascade not supported in ") - << stringifyAIEArch(targetModel.getTargetArch()); + } + if (numOp > 1) { + return emitOpError("cannot have more than one ConnectOp in CascadeSwitchboxOp"); } return success(); } +int CascadeSwitchboxOp::colIndex() { + return getTileOp().colIndex(); +} + +int CascadeSwitchboxOp::rowIndex() { + return getTileOp().rowIndex(); +} + +TileOp CascadeSwitchboxOp::getTileOp() { + return cast(getTile().getDefiningOp()); +} + //===----------------------------------------------------------------------===// // PutCascadeOp //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp b/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp index bc9d29dc55..21bf446a1d 100644 --- a/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp +++ b/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp @@ -570,7 +570,8 @@ struct AIECoreToStandardPass : AIECoreToStandardBase { AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, - AIEOpRemoval, AIEOpRemoval>( + AIEOpRemoval, AIEOpRemoval, + AIEOpRemoval, AIEOpRemoval>( m.getContext(), m); if (failed(applyPartialConversion(m, target, std::move(removepatterns)))) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp new file mode 100644 index 0000000000..e966eff7ad --- /dev/null +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -0,0 +1,109 @@ +//===- AIELowerCascadeFlows.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 2024 Xilinx Inc. +// +//===----------------------------------------------------------------------===// + +#include "aie/Dialect/AIE/IR/AIEDialect.h" +#include "aie/Dialect/AIE/Transforms/AIEPasses.h" + +#include "mlir/IR/Attributes.h" +#include "mlir/Pass/Pass.h" + +#include "llvm/ADT/Twine.h" + +#define DEBUG_TYPE "aie-lower-cascade-flows" + +using namespace mlir; +using namespace xilinx; +using namespace xilinx::AIE; + +CascadeSwitchboxOp getOrCreateCascadeSwitchbox(OpBuilder &builder, TileOp tile) { + for (auto i : tile.getResult().getUsers()) { + if (llvm::isa(*i)) { + return llvm::cast(*i); + } + } + return builder.create(builder.getUnknownLoc(), tile); +} + +struct AIELowerCascadeFlowsPass + : AIELowerCascadeFlowsBase { + void getDependentDialects(DialectRegistry ®istry) const override { + registry.insert(); + } + void runOnOperation() override { + DeviceOp device = getOperation(); + const auto &targetModel = device.getTargetModel(); + OpBuilder builder = OpBuilder::atBlockEnd(device.getBody()); + + std::vector tilesWithCascadeFlow; + DenseMap cascadeInputsPerTile; + DenseMap cascadeOutputsPerTile; + + // identify cascade_flows and what ports they use on each tile + for (auto cascadeFlow : device.getOps()) { + // for each cascade flow + TileOp src = cascadeFlow.getSourceTileOp(); + TileOp dst = cascadeFlow.getDestTileOp(); + tilesWithCascadeFlow.push_back(src); + tilesWithCascadeFlow.push_back(dst); + + if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + cascadeInputsPerTile[dst] = WireBundle::North; + cascadeOutputsPerTile[src] = WireBundle::South; + } else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + cascadeInputsPerTile[dst] = WireBundle::West; + cascadeOutputsPerTile[src] = WireBundle::East; + } else { + // TODO: remove when this pass supports routing + cascadeFlow.emitOpError("source tile must be to the North or West of the destination tile"); + return; + } + } + + // generate cascade switchboxes + for (TileOp tile : tilesWithCascadeFlow) { + CascadeSwitchboxOp swbox = getOrCreateCascadeSwitchbox(builder, tile); + CascadeSwitchboxOp::ensureTerminator(swbox.getConnections(), builder, + builder.getUnknownLoc()); + Block &b = swbox.getConnections().front(); + builder.setInsertionPoint(b.getTerminator()); + + WireBundle inputDir; + if (cascadeInputsPerTile.find(tile) != cascadeInputsPerTile.end()) { + inputDir = cascadeInputsPerTile[tile]; + } else { + inputDir = WireBundle::North; + } + WireBundle outputDir; + if (cascadeOutputsPerTile.find(tile) != cascadeOutputsPerTile.end()) { + outputDir = cascadeOutputsPerTile[tile]; + } else { + outputDir = WireBundle::South; + } + int channelIndex = 0; + builder.create(builder.getUnknownLoc(), inputDir, channelIndex, outputDir, channelIndex); + builder.setInsertionPointAfter(swbox); + } + + // erase CascadeFlowOps + SetVector opsToErase; + device.walk([&](Operation *op) { + if (isa(op)) + opsToErase.insert(op); + }); + IRRewriter rewriter(&getContext()); + for (auto it = opsToErase.rbegin(); it != opsToErase.rend(); ++it) + (*it)->erase(); + } +}; + +std::unique_ptr> +AIE::createAIELowerCascadeFlowsPass() { + return std::make_unique(); +} diff --git a/lib/Dialect/AIE/Transforms/CMakeLists.txt b/lib/Dialect/AIE/Transforms/CMakeLists.txt index ef83221497..561f3796ac 100644 --- a/lib/Dialect/AIE/Transforms/CMakeLists.txt +++ b/lib/Dialect/AIE/Transforms/CMakeLists.txt @@ -20,6 +20,7 @@ add_mlir_dialect_library( AIEVectorOpt.cpp AIEObjectFifoStatefulTransform.cpp AIEObjectFifoRegisterProcess.cpp + AIELowerCascadeFlows.cpp ADDITIONAL_HEADER_DIRS ${AIE_BINARY_DIR}/include diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index 6c78a00ed3..60adf7b434 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1064,26 +1064,31 @@ static void configureSwitchBoxes(DeviceOp &targetOp) { static void configureCascade(DeviceOp &targetOp) { const auto &target_model = xilinx::AIE::getTargetModel(targetOp); if (target_model.getTargetArch() == AIEArch::AIE2) { - for (auto configOp : targetOp.getOps()) { - TileOp tile = cast(configOp.getTile().getDefiningOp()); - auto inputDir = stringifyCascadeDir(configOp.getInputDir()).upper(); - auto outputDir = stringifyCascadeDir(configOp.getOutputDir()).upper(); + for (auto cascadeSwboxOp : targetOp.getOps()) { + TileOp tile = cascadeSwboxOp.getTileOp(); + Region &body = cascadeSwboxOp.getConnections(); + for (auto &ops : body.front()) { + if (auto connectOp = dyn_cast(ops)) { + auto inputDir = stringifyWireBundle(connectOp.getSourceBundle()).upper(); + auto outputDir = stringifyWireBundle(connectOp.getDestBundle()).upper(); - Address address{tile, 0x36060u}; + Address address{tile, 0x36060u}; - /* - * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST - * * Register value for input BIT 0: 0 == NORTH, 1 == WEST - */ - uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; - uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; + /* + * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST + * * Register value for input BIT 0: 0 == NORTH, 1 == WEST + */ + uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; + uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; - constexpr Field<1> Output; - constexpr Field<0> Input; + constexpr Field<1> Output; + constexpr Field<0> Input; - auto regValue = Output(outputValue) | Input(inputValue); + auto regValue = Output(outputValue) | Input(inputValue); - write32(address, regValue); + write32(address, regValue); + } + } } } } @@ -1211,7 +1216,7 @@ mlir::LogicalResult AIETranslateToAirbin(mlir::ModuleOp module, } configureSwitchBoxes(targetOp); - configureCascade(targetOp); + //configureCascade(targetOp); configureDMAs(targetOp); groupSections(sections); diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 63c34d5c9d..159ca299a5 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -700,15 +700,20 @@ struct AIEControl { // Cascade configuration const auto &target_model = xilinx::AIE::getTargetModel(targetOp); if (target_model.getTargetArch() == AIEArch::AIE2) { - for (auto configOp : targetOp.getOps()) { - TileOp tile = cast(configOp.getTile().getDefiningOp()); - auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); - TRY_XAIE_API_EMIT_ERROR( - targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - static_cast(configOp.getInputDir())), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - static_cast(configOp.getOutputDir()))); + for (auto cascadeSwboxOp : targetOp.getOps()) { + TileOp tile = cascadeSwboxOp.getTileOp(); + Region &body = cascadeSwboxOp.getConnections(); + for (auto &ops : body.front()) { + if (auto connectOp = dyn_cast(ops)) { + auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); + TRY_XAIE_API_EMIT_ERROR( + targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + connectOp.getSourceBundle()), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + connectOp.getDestBundle())); + } + } } } diff --git a/lib/Targets/AIETargetXAIEV2.cpp b/lib/Targets/AIETargetXAIEV2.cpp index 11b0e1c424..ee6914b101 100644 --- a/lib/Targets/AIETargetXAIEV2.cpp +++ b/lib/Targets/AIETargetXAIEV2.cpp @@ -769,14 +769,21 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { // mlir_aie_configure_cascade //--------------------------------------------------------------------------- output << "int mlir_aie_configure_cascade(" << ctx_p << ") {\n"; - for (auto configOp : targetOp.getOps()) { - TileOp tile = cast(configOp.getTile().getDefiningOp()); + for (auto cascadeSwboxOp : targetOp.getOps()) { + TileOp tile = cascadeSwboxOp.getTileOp(); int col = tile.colIndex(); int row = tile.rowIndex(); - output << "XAie_CoreConfigAccumulatorControl(" << deviceInstRef << ", " - << "XAie_TileLoc(" << col << ", " << row << "), " - << stringifyCascadeDir(configOp.getInputDir()).upper() << ", " - << stringifyCascadeDir(configOp.getOutputDir()).upper() << ");\n"; + Region &body = cascadeSwboxOp.getConnections(); + for (auto &ops : body.front()) { + if (auto connectOp = dyn_cast(ops)) { + WireBundle inputDir = connectOp.getSourceBundle(); + WireBundle outputDir = connectOp.getDestBundle(); + output << "XAie_CoreConfigAccumulatorControl(" << deviceInstRef << ", " + << "XAie_TileLoc(" << col << ", " << row << "), " + << stringifyWireBundle(inputDir).upper() << ", " + << stringifyWireBundle(outputDir).upper() << ");\n"; + } + } } output << "return XAIE_OK;\n"; output << "} // mlir_aie_configure_cascade\n\n"; diff --git a/test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir b/test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir new file mode 100644 index 0000000000..45360a9e9a --- /dev/null +++ b/test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir @@ -0,0 +1,40 @@ +//===- aie2_cascade_flow.mlir -----------------------------------*- MLIR -*-===// +// +// 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 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// RUN: aie-translate --aie-generate-xaie %s | FileCheck %s + +// CHECK: int mlir_aie_configure_cascade(aie_libxaie_ctx_t* ctx) { +// CHECK: XAie_CoreConfigAccumulatorControl(&(ctx->DevInst), XAie_TileLoc(1, 3), NORTH, EAST); +// CHECK: XAie_CoreConfigAccumulatorControl(&(ctx->DevInst), XAie_TileLoc(2, 3), WEST, SOUTH); +// CHECK: XAie_CoreConfigAccumulatorControl(&(ctx->DevInst), XAie_TileLoc(3, 4), NORTH, SOUTH); +// CHECK: XAie_CoreConfigAccumulatorControl(&(ctx->DevInst), XAie_TileLoc(3, 3), NORTH, SOUTH); +// CHECK: return XAIE_OK; +// CHECK: } // mlir_aie_configure_cascade + +module @cascade_flow { + aie.device(xcve2802) { + %tile_1_3 = aie.tile(1, 3) + %tile_2_3 = aie.tile(2, 3) + %tile_3_4 = aie.tile(3, 4) + %tile_3_3 = aie.tile(3, 3) + %cascade_switchbox_1_3 = aie.cascade_switchbox(%tile_1_3) { + aie.connect + } + %cascade_switchbox_2_3 = aie.cascade_switchbox(%tile_2_3) { + aie.connect + } + %cascade_switchbox_3_4 = aie.cascade_switchbox(%tile_3_4) { + aie.connect + } + %cascade_switchbox_3_3 = aie.cascade_switchbox(%tile_3_3) { + aie.connect + } + } +} diff --git a/test/dialect/AIE/bad_cascade.mlir b/test/dialect/AIE/bad_cascade.mlir index 7e14b5fe1a..87c233014c 100644 --- a/test/dialect/AIE/bad_cascade.mlir +++ b/test/dialect/AIE/bad_cascade.mlir @@ -9,27 +9,55 @@ //===----------------------------------------------------------------------===// // RUN: not aie-opt -split-input-file %s 2>&1 | FileCheck %s -// CHECK: error{{.*}}'aie.configure_cascade' op input direction of cascade must be North or West on AIE2 +// CHECK: error{{.*}}'aie.cascade_flow' op tiles must be adjacent aie.device(xcve2802) { %t13 = aie.tile(1, 3) - aie.configure_cascade(%t13, East, South) + %t33 = aie.tile(3, 3) + aie.cascade_flow(%t13, %t33) } // ----- -// CHECK: error{{.*}}'aie.configure_cascade' op output direction of cascade must be South or East on AIE2 +// CHECK: error{{.*}}'aie.cascade_switchbox' op cannot have more than one ConnectOp in CascadeSwitchboxOp aie.device(xcve2802) { %t13 = aie.tile(1, 3) - aie.configure_cascade(%t13, North, West) + aie.cascade_switchbox(%t13) { + aie.connect + aie.connect + } } // ----- -// CHECK: error{{.*}}'aie.configure_cascade' op cascade not supported in AIE1 +// CHECK: error{{.*}}'aie.connect' op portIndex of ConnectOp is out-of-bounds -aie.device(xcvc1902) { +aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + aie.cascade_switchbox(%t13) { + aie.connect + } +} + +// ----- + +// CHECK: error{{.*}}'aie.connect' op source port of ConnectOp in CascadeSwitchboxOp must be West or North + +aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + aie.cascade_switchbox(%t13) { + aie.connect + } +} + +// ----- + +// CHECK: error{{.*}}'aie.connect' op dest port of ConnectOp in CascadeSwitchboxOp must be East or South + +aie.device(xcve2802) { %t13 = aie.tile(1, 3) - aie.configure_cascade(%t13, North, East) + aie.cascade_switchbox(%t13) { + aie.connect + } } diff --git a/test/dialect/AIE/cascade_configure.mlir b/test/dialect/AIE/cascade_flow.mlir similarity index 75% rename from test/dialect/AIE/cascade_configure.mlir rename to test/dialect/AIE/cascade_flow.mlir index 89c8399f67..b14eb3957e 100644 --- a/test/dialect/AIE/cascade_configure.mlir +++ b/test/dialect/AIE/cascade_flow.mlir @@ -1,4 +1,4 @@ -//===- cascade_configure.mlir -----------------------------------*- MLIR -*-===// +//===- cascade_flow.mlir ----------------------------------------*- MLIR -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -14,7 +14,6 @@ module @test { aie.device(xcve2802) { %t13 = aie.tile(1, 3) %t23 = aie.tile(2, 3) - aie.configure_cascade(%t13, West, East) - aie.configure_cascade(%t23, North, South) + aie.cascade_flow(%t13, %t23) } } diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/configure_cascade/aie.mlir index f460e59f12..967c3ecedc 100644 --- a/test/ipu-xrt/configure_cascade/aie.mlir +++ b/test/ipu-xrt/configure_cascade/aie.mlir @@ -13,9 +13,8 @@ module { %t13 = aie.tile(1, 3) %t12 = aie.tile(1, 2) - aie.configure_cascade(%t03, West, East) - aie.configure_cascade(%t13, West, South) - aie.configure_cascade(%t12, North, South) + aie.cascade_flow(%t03, %t13) + aie.cascade_flow(%t13, %t12) aie.objectfifo @objFifo_in0(%t00, {%t01}, 1 : i32) : !aie.objectfifo> aie.objectfifo @objFifo_in1(%t01, {%t03}, 1 : i32) : !aie.objectfifo> diff --git a/test/lower-cascade-flows/cascade_flow.mlir b/test/lower-cascade-flows/cascade_flow.mlir new file mode 100644 index 0000000000..9981f67e7f --- /dev/null +++ b/test/lower-cascade-flows/cascade_flow.mlir @@ -0,0 +1,44 @@ +//===- cascade_flow.mlir ----------------------------------------*- MLIR -*-===// +// +// 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 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// RUN: aie-opt --aie-lower-cascade-flows %s | FileCheck %s + +// CHECK: module @cascade_flow { +// CHECK: aie.device(xcve2802) { +// CHECK: %tile_1_3 = aie.tile(1, 3) +// CHECK: %tile_2_3 = aie.tile(2, 3) +// CHECK: %tile_3_4 = aie.tile(3, 4) +// CHECK: %tile_3_3 = aie.tile(3, 3) +// CHECK: %cascade_switchbox_1_3 = aie.cascade_switchbox(%tile_1_3) { +// CHECK: aie.connect +// CHECK: } +// CHECK: %cascade_switchbox_2_3 = aie.cascade_switchbox(%tile_2_3) { +// CHECK: aie.connect +// CHECK: } +// CHECK: %cascade_switchbox_3_4 = aie.cascade_switchbox(%tile_3_4) { +// CHECK: aie.connect +// CHECK: } +// CHECK: %cascade_switchbox_3_3 = aie.cascade_switchbox(%tile_3_3) { +// CHECK: aie.connect +// CHECK: } +// CHECK: } +// CHECK: } + +module @cascade_flow { + aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + %t23 = aie.tile(2, 3) + aie.cascade_flow(%t13, %t23) + + %t34 = aie.tile(3, 4) + %t33 = aie.tile(3, 3) + aie.cascade_flow(%t34, %t33) + } +} diff --git a/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir b/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir index 50a4765f1e..5854b70b07 100644 --- a/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir +++ b/test/unit_tests/aie2/03_cascade_core_functions/aie.mlir @@ -20,8 +20,7 @@ module { %tile13 = aie.tile(1, 3) %tile23 = aie.tile(2, 3) - aie.configure_cascade(%tile13, West, East) - aie.configure_cascade(%tile23, West, East) + aie.cascade_flow(%tile13, %tile23) %buf13_0 = aie.buffer(%tile13) { sym_name = "a" } : memref<256xi32> %buf23_0 = aie.buffer(%tile23) { sym_name = "c" } : memref<256xi32> From 53e2420ad5d7251c557df55ab7e8ca528a3a919f Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:36:06 +0100 Subject: [PATCH 25/51] Update include/aie/Dialect/AIE/Transforms/AIEPasses.h Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- include/aie/Dialect/AIE/Transforms/AIEPasses.h | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/include/aie/Dialect/AIE/Transforms/AIEPasses.h b/include/aie/Dialect/AIE/Transforms/AIEPasses.h index 550f53e727..be7326822a 100644 --- a/include/aie/Dialect/AIE/Transforms/AIEPasses.h +++ b/include/aie/Dialect/AIE/Transforms/AIEPasses.h @@ -41,8 +41,7 @@ std::unique_ptr> createAIEObjectFifoStatefulTransformPass(); std::unique_ptr> createAIEObjectFifoRegisterProcessPass(); -std::unique_ptr> -createAIELowerCascadeFlowsPass(); +std::unique_ptr> createAIELowerCascadeFlowsPass(); /// Generate the code for registering passes. #define GEN_PASS_REGISTRATION From 0c15e6b61fcf3cf43105b8cb8359ab943ecd9e7b Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:36:23 +0100 Subject: [PATCH 26/51] Update lib/Dialect/AIE/IR/AIEDialect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/IR/AIEDialect.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 8b2d5911a3..58cd3c23b4 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -872,11 +872,11 @@ LogicalResult CascadeFlowOp::verify() { TileOp src = getSourceTileOp(); TileOp dst = getDestTileOp(); const auto &t = getTargetModel(src); - 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"); + 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(); } From 3ee1bdfdfa61e09e5a889310b635184689d053dd Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:36:35 +0100 Subject: [PATCH 27/51] Update lib/Dialect/AIE/IR/AIEDialect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/IR/AIEDialect.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 58cd3c23b4..e1ff2eb8d7 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -904,7 +904,9 @@ LogicalResult CascadeSwitchboxOp::verify() { numOp++; WireBundle inDir = connectOp.getSourceBundle(); if (inDir != WireBundle::West && inDir != WireBundle::North) { - return connectOp.emitOpError("source port of ConnectOp in CascadeSwitchboxOp must be West or North"); + return connectOp.emitOpError( + "source port of ConnectOp in CascadeSwitchboxOp must be West or " + "North"); } WireBundle outDir = connectOp.getDestBundle(); if (outDir != WireBundle::East && outDir != WireBundle::South) { From 01774990954f93b8dc68fbacd72d57781b31529f Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:36:49 +0100 Subject: [PATCH 28/51] Update lib/Dialect/AIE/IR/AIEDialect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/IR/AIEDialect.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index e1ff2eb8d7..0010f7e3d2 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -910,7 +910,9 @@ LogicalResult CascadeSwitchboxOp::verify() { } WireBundle outDir = connectOp.getDestBundle(); if (outDir != WireBundle::East && outDir != WireBundle::South) { - return connectOp.emitOpError("dest port of ConnectOp in CascadeSwitchboxOp must be East or South"); + return connectOp.emitOpError( + "dest port of ConnectOp in CascadeSwitchboxOp must be East or " + "South"); } if (connectOp.sourceIndex() != 0 || connectOp.destIndex() != 0) { return connectOp.emitOpError("portIndex of ConnectOp is out-of-bounds"); From a0c37b2e773f60c62db6eb36f6708ab868ea91e3 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:37:04 +0100 Subject: [PATCH 29/51] Update lib/Dialect/AIE/IR/AIEDialect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/IR/AIEDialect.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 0010f7e3d2..c0b14a369a 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -924,7 +924,8 @@ LogicalResult CascadeSwitchboxOp::verify() { } } if (numOp > 1) { - return emitOpError("cannot have more than one ConnectOp in CascadeSwitchboxOp"); + return emitOpError( + "cannot have more than one ConnectOp in CascadeSwitchboxOp"); } return success(); } From ef537f4b570f3fe4482b548eef6cfa4af966e622 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:37:59 +0100 Subject: [PATCH 30/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index e966eff7ad..d50498a5ca 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -103,7 +103,6 @@ struct AIELowerCascadeFlowsPass } }; -std::unique_ptr> -AIE::createAIELowerCascadeFlowsPass() { +std::unique_ptr> AIE::createAIELowerCascadeFlowsPass() { return std::make_unique(); } From dded7d7c8b1bd84e5163590f9902d95101db15df Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:38:26 +0100 Subject: [PATCH 31/51] Update lib/Targets/AIETargetAirbin.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Targets/AIETargetAirbin.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index 60adf7b434..8fc9587ae7 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1075,9 +1075,9 @@ static void configureCascade(DeviceOp &targetOp) { Address address{tile, 0x36060u}; /* - * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST - * * Register value for input BIT 0: 0 == NORTH, 1 == WEST - */ + * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST + * * Register value for input BIT 0: 0 == NORTH, 1 == WEST + */ uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; From a0304f2600ca205c3bc20f32c3f28d3a0357f9e3 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:40:35 +0100 Subject: [PATCH 32/51] Update lib/Targets/AIETargetAirbin.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Targets/AIETargetAirbin.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index 8fc9587ae7..7fa85af877 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1069,8 +1069,10 @@ static void configureCascade(DeviceOp &targetOp) { Region &body = cascadeSwboxOp.getConnections(); for (auto &ops : body.front()) { if (auto connectOp = dyn_cast(ops)) { - auto inputDir = stringifyWireBundle(connectOp.getSourceBundle()).upper(); - auto outputDir = stringifyWireBundle(connectOp.getDestBundle()).upper(); + auto inputDir = + stringifyWireBundle(connectOp.getSourceBundle()).upper(); + auto outputDir = + stringifyWireBundle(connectOp.getDestBundle()).upper(); Address address{tile, 0x36060u}; From 18aaca86b5aeab145360f496f4be7bbed5b44dcd Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:41:06 +0100 Subject: [PATCH 33/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index d50498a5ca..ead88bc54a 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -22,7 +22,8 @@ using namespace mlir; using namespace xilinx; using namespace xilinx::AIE; -CascadeSwitchboxOp getOrCreateCascadeSwitchbox(OpBuilder &builder, TileOp tile) { +CascadeSwitchboxOp getOrCreateCascadeSwitchbox(OpBuilder &builder, + TileOp tile) { for (auto i : tile.getResult().getUsers()) { if (llvm::isa(*i)) { return llvm::cast(*i); From 57d6b08870153d49eeba9d308af8bd59c202fe87 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:41:27 +0100 Subject: [PATCH 34/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index ead88bc54a..2b42e3be35 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -57,7 +57,8 @@ struct AIELowerCascadeFlowsPass if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { cascadeInputsPerTile[dst] = WireBundle::North; cascadeOutputsPerTile[src] = WireBundle::South; - } else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + } else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(), + dst.getRow())) { cascadeInputsPerTile[dst] = WireBundle::West; cascadeOutputsPerTile[src] = WireBundle::East; } else { From c4602e9ad72754c97834bc94cb18c5d9b3d6b2ee Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:41:47 +0100 Subject: [PATCH 35/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index 2b42e3be35..efe8dbfca1 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -54,7 +54,8 @@ struct AIELowerCascadeFlowsPass tilesWithCascadeFlow.push_back(src); tilesWithCascadeFlow.push_back(dst); - if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), + dst.getRow())) { cascadeInputsPerTile[dst] = WireBundle::North; cascadeOutputsPerTile[src] = WireBundle::South; } else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(), From 7421cc0d7610b65a7231ce7e25add5be728e9926 Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:42:04 +0100 Subject: [PATCH 36/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index efe8dbfca1..d512b65b3b 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -64,7 +64,8 @@ struct AIELowerCascadeFlowsPass cascadeOutputsPerTile[src] = WireBundle::East; } else { // TODO: remove when this pass supports routing - cascadeFlow.emitOpError("source tile must be to the North or West of the destination tile"); + cascadeFlow.emitOpError( + "source tile must be to the North or West of the destination tile"); return; } } From 1c777259dc8c97fa42a9582579439f484920559a Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:42:21 +0100 Subject: [PATCH 37/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index d512b65b3b..13da4dcb07 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -91,7 +91,8 @@ struct AIELowerCascadeFlowsPass outputDir = WireBundle::South; } int channelIndex = 0; - builder.create(builder.getUnknownLoc(), inputDir, channelIndex, outputDir, channelIndex); + builder.create(builder.getUnknownLoc(), inputDir, channelIndex, + outputDir, channelIndex); builder.setInsertionPointAfter(swbox); } From 42253806abbe91302075f2e782b039d92d5a864f Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Tue, 13 Feb 2024 14:42:58 +0100 Subject: [PATCH 38/51] Update lib/Targets/AIETargetCDODirect.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Targets/AIETargetCDODirect.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 1a8075a9fe..0e767c18d9 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -714,8 +714,7 @@ struct AIEControl { targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( connectOp.getSourceBundle()), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - connectOp.getDestBundle())); + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle())); } } } From e716656551d3be6296b1f14e5560c0e3d639c468 Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 13 Feb 2024 08:45:21 -0700 Subject: [PATCH 39/51] Clang format --- include/aie/Dialect/AIE/IR/AIEOps.td | 6 +++--- lib/Dialect/AIE/IR/AIEDialect.cpp | 19 ++++++++++++------- .../AIE/Transforms/AIELowerCascadeFlows.cpp | 18 +++++++++++------- lib/Targets/AIETargetAirbin.cpp | 2 +- lib/Targets/AIETargetCDODirect.cpp | 3 +-- 5 files changed, 28 insertions(+), 20 deletions(-) diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index 957940b3a8..fe2d158ff1 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -1345,8 +1345,8 @@ def AIE_PutStreamOp: AIE_Op<"put_stream", [HasParent<"CoreOp">]> { def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { let arguments = ( - ins Index:$sourceTile, - Index:$destTile + ins Index:$source_tile, + Index:$dest_tile ); let summary = "A cascade connection between tiles"; let description = [{ @@ -1363,7 +1363,7 @@ def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { }]; let hasVerifier = 1; let assemblyFormat = [{ - `(` $sourceTile `,` $destTile `)` attr-dict + `(` $source_tile `,` $dest_tile `)` attr-dict }]; let extraClassDeclaration = [{ TileOp getSourceTileOp(); diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 8b2d5911a3..17716a0dd3 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -872,10 +872,10 @@ LogicalResult CascadeFlowOp::verify() { TileOp src = getSourceTileOp(); TileOp dst = getDestTileOp(); const auto &t = getTargetModel(src); - 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())) { + 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(); @@ -904,11 +904,15 @@ LogicalResult CascadeSwitchboxOp::verify() { numOp++; WireBundle inDir = connectOp.getSourceBundle(); if (inDir != WireBundle::West && inDir != WireBundle::North) { - return connectOp.emitOpError("source port of ConnectOp in CascadeSwitchboxOp must be West or North"); + return connectOp.emitOpError( + "source port of ConnectOp in CascadeSwitchboxOp must be West or " + "North"); } WireBundle outDir = connectOp.getDestBundle(); if (outDir != WireBundle::East && outDir != WireBundle::South) { - return connectOp.emitOpError("dest port of ConnectOp in CascadeSwitchboxOp must be East or South"); + return connectOp.emitOpError( + "dest port of ConnectOp in CascadeSwitchboxOp must be East or " + "South"); } if (connectOp.sourceIndex() != 0 || connectOp.destIndex() != 0) { return connectOp.emitOpError("portIndex of ConnectOp is out-of-bounds"); @@ -920,7 +924,8 @@ LogicalResult CascadeSwitchboxOp::verify() { } } if (numOp > 1) { - return emitOpError("cannot have more than one ConnectOp in CascadeSwitchboxOp"); + return emitOpError( + "cannot have more than one ConnectOp in CascadeSwitchboxOp"); } return success(); } diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index e966eff7ad..43aa16c238 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -22,7 +22,8 @@ using namespace mlir; using namespace xilinx; using namespace xilinx::AIE; -CascadeSwitchboxOp getOrCreateCascadeSwitchbox(OpBuilder &builder, TileOp tile) { +CascadeSwitchboxOp getOrCreateCascadeSwitchbox(OpBuilder &builder, + TileOp tile) { for (auto i : tile.getResult().getUsers()) { if (llvm::isa(*i)) { return llvm::cast(*i); @@ -53,15 +54,18 @@ struct AIELowerCascadeFlowsPass tilesWithCascadeFlow.push_back(src); tilesWithCascadeFlow.push_back(dst); - if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), + dst.getRow())) { cascadeInputsPerTile[dst] = WireBundle::North; cascadeOutputsPerTile[src] = WireBundle::South; - } else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { + } else if (targetModel.isEast(src.getCol(), src.getRow(), dst.getCol(), + dst.getRow())) { cascadeInputsPerTile[dst] = WireBundle::West; cascadeOutputsPerTile[src] = WireBundle::East; } else { // TODO: remove when this pass supports routing - cascadeFlow.emitOpError("source tile must be to the North or West of the destination tile"); + cascadeFlow.emitOpError( + "source tile must be to the North or West of the destination tile"); return; } } @@ -87,7 +91,8 @@ struct AIELowerCascadeFlowsPass outputDir = WireBundle::South; } int channelIndex = 0; - builder.create(builder.getUnknownLoc(), inputDir, channelIndex, outputDir, channelIndex); + builder.create(builder.getUnknownLoc(), inputDir, channelIndex, + outputDir, channelIndex); builder.setInsertionPointAfter(swbox); } @@ -103,7 +108,6 @@ struct AIELowerCascadeFlowsPass } }; -std::unique_ptr> -AIE::createAIELowerCascadeFlowsPass() { +std::unique_ptr> AIE::createAIELowerCascadeFlowsPass() { return std::make_unique(); } diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index 60adf7b434..f9029f37e2 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1216,7 +1216,7 @@ mlir::LogicalResult AIETranslateToAirbin(mlir::ModuleOp module, } configureSwitchBoxes(targetOp); - //configureCascade(targetOp); + configureCascade(targetOp); configureDMAs(targetOp); groupSections(sections); diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 1a8075a9fe..0e767c18d9 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -714,8 +714,7 @@ struct AIEControl { targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( connectOp.getSourceBundle()), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - connectOp.getDestBundle())); + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle())); } } } From 3e6d9ca563b63fe78b6d13660aeaa6c65cceb054 Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 13 Feb 2024 09:38:13 -0700 Subject: [PATCH 40/51] Clang format --- lib/Dialect/AIE/IR/AIEDialect.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index c0b14a369a..15cc60dc4b 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -930,13 +930,9 @@ LogicalResult CascadeSwitchboxOp::verify() { return success(); } -int CascadeSwitchboxOp::colIndex() { - return getTileOp().colIndex(); -} +int CascadeSwitchboxOp::colIndex() { return getTileOp().colIndex(); } -int CascadeSwitchboxOp::rowIndex() { - return getTileOp().rowIndex(); -} +int CascadeSwitchboxOp::rowIndex() { return getTileOp().rowIndex(); } TileOp CascadeSwitchboxOp::getTileOp() { return cast(getTile().getDefiningOp()); From 1ddf679fa184dafe1daf5332a05b86d2e1b1b928 Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 13 Feb 2024 11:04:24 -0700 Subject: [PATCH 41/51] Add tests for memtiles and shimtiles --- lib/Dialect/AIE/IR/AIEDialect.cpp | 12 ++++++ test/dialect/AIE/bad_cascade.mlir | 63 +++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 15cc60dc4b..e620370d23 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -872,6 +872,13 @@ 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()) && @@ -894,9 +901,14 @@ TileOp CascadeFlowOp::getDestTileOp() { //===----------------------------------------------------------------------===// LogicalResult CascadeSwitchboxOp::verify() { + const auto &targetModel = getTargetModel(*this); Region &body = getConnections(); if (body.empty()) return emitOpError("should have non-empty body"); + if (getTileOp().isShimTile()) + return emitOpError("shimTile row has no cascade stream interface"); + if (targetModel.isMemTile(colIndex(), rowIndex())) + return emitOpError("memTile row has no cascade stream interface"); int numOp = 0; for (auto &ops : body.front()) { diff --git a/test/dialect/AIE/bad_cascade.mlir b/test/dialect/AIE/bad_cascade.mlir index 87c233014c..56041cf82b 100644 --- a/test/dialect/AIE/bad_cascade.mlir +++ b/test/dialect/AIE/bad_cascade.mlir @@ -19,6 +19,69 @@ aie.device(xcve2802) { // ----- +// CHECK: error{{.*}}'aie.cascade_flow' op memTile row has no cascade stream interface + +aie.device(xcve2802) { + %t12 = aie.tile(1, 2) + %t22 = aie.tile(2, 2) + aie.cascade_flow(%t12, %t22) +} + +// ----- + +// CHECK: error{{.*}}'aie.cascade_flow' op shimTile row has no cascade stream interface + +aie.device(ipu) { + %t10 = aie.tile(1, 0) + %t20 = aie.tile(2, 0) + aie.cascade_flow(%t10, %t20) +} + +// ----- + +// CHECK: error{{.*}}'aie.cascade_flow' op memTile row has no cascade stream interface + +aie.device(ipu) { + %t11 = aie.tile(1, 1) + %t21 = aie.tile(2, 1) + aie.cascade_flow(%t11, %t21) +} + +// ----- + +// CHECK: error{{.*}}'aie.cascade_switchbox' op memTile row has no cascade stream interface + +aie.device(xcve2802) { + %t12 = aie.tile(1, 2) + aie.cascade_switchbox(%t12) { + aie.connect + } +} + +// ----- + +// CHECK: error{{.*}}'aie.cascade_switchbox' op shimTile row has no cascade stream interface + +aie.device(ipu) { + %t10 = aie.tile(1, 0) + aie.cascade_switchbox(%t10) { + aie.connect + } +} + +// ----- + +// CHECK: error{{.*}}'aie.cascade_switchbox' op memTile row has no cascade stream interface + +aie.device(ipu) { + %t11 = aie.tile(1, 1) + aie.cascade_switchbox(%t11) { + aie.connect + } +} + +// ----- + // CHECK: error{{.*}}'aie.cascade_switchbox' op cannot have more than one ConnectOp in CascadeSwitchboxOp aie.device(xcve2802) { From 799a1d67ddfddbf0d06e625933a8ad5980338800 Mon Sep 17 00:00:00 2001 From: abisca Date: Tue, 13 Feb 2024 11:48:34 -0700 Subject: [PATCH 42/51] Fix issue of cascade_flow lowering to cascade switchboxes with multiple connect ops --- .../AIE/Transforms/AIELowerCascadeFlows.cpp | 6 +-- ...ade_flow.mlir => cascade_single_flow.mlir} | 2 +- .../cascade_two_flows.mlir | 38 +++++++++++++++++++ 3 files changed, 42 insertions(+), 4 deletions(-) rename test/lower-cascade-flows/{cascade_flow.mlir => cascade_single_flow.mlir} (95%) create mode 100644 test/lower-cascade-flows/cascade_two_flows.mlir diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index 13da4dcb07..ca56ba2a1b 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -42,7 +42,7 @@ struct AIELowerCascadeFlowsPass const auto &targetModel = device.getTargetModel(); OpBuilder builder = OpBuilder::atBlockEnd(device.getBody()); - std::vector tilesWithCascadeFlow; + std::set tilesWithCascadeFlow; DenseMap cascadeInputsPerTile; DenseMap cascadeOutputsPerTile; @@ -51,8 +51,8 @@ struct AIELowerCascadeFlowsPass // for each cascade flow TileOp src = cascadeFlow.getSourceTileOp(); TileOp dst = cascadeFlow.getDestTileOp(); - tilesWithCascadeFlow.push_back(src); - tilesWithCascadeFlow.push_back(dst); + tilesWithCascadeFlow.insert(src); + tilesWithCascadeFlow.insert(dst); if (targetModel.isSouth(src.getCol(), src.getRow(), dst.getCol(), dst.getRow())) { diff --git a/test/lower-cascade-flows/cascade_flow.mlir b/test/lower-cascade-flows/cascade_single_flow.mlir similarity index 95% rename from test/lower-cascade-flows/cascade_flow.mlir rename to test/lower-cascade-flows/cascade_single_flow.mlir index 9981f67e7f..92d4d60688 100644 --- a/test/lower-cascade-flows/cascade_flow.mlir +++ b/test/lower-cascade-flows/cascade_single_flow.mlir @@ -1,4 +1,4 @@ -//===- cascade_flow.mlir ----------------------------------------*- MLIR -*-===// +//===- cascade_single_flow.mlir ---------------------------------*- MLIR -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/test/lower-cascade-flows/cascade_two_flows.mlir b/test/lower-cascade-flows/cascade_two_flows.mlir new file mode 100644 index 0000000000..79f3be4f40 --- /dev/null +++ b/test/lower-cascade-flows/cascade_two_flows.mlir @@ -0,0 +1,38 @@ +//===- cascade_two_flows.mlir -----------------------------------*- MLIR -*-===// +// +// 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 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// RUN: aie-opt --aie-lower-cascade-flows %s | FileCheck %s + +// CHECK: module @cascade_flow { +// CHECK: aie.device(xcve2802) { +// CHECK: %tile_1_4 = aie.tile(1, 4) +// CHECK: %tile_2_4 = aie.tile(2, 4) +// CHECK: %tile_3_4 = aie.tile(3, 4) +// CHECK: %cascade_switchbox_1_4 = aie.cascade_switchbox(%tile_1_4) { +// CHECK: aie.connect +// CHECK: } +// CHECK: %cascade_switchbox_2_4 = aie.cascade_switchbox(%tile_2_4) { +// CHECK: aie.connect +// CHECK: } +// CHECK: %cascade_switchbox_3_4 = aie.cascade_switchbox(%tile_3_4) { +// CHECK: aie.connect +// CHECK: } +// CHECK: } +// CHECK: } + +module @cascade_flow { + aie.device(xcve2802) { + %t14 = aie.tile(1, 4) + %t24 = aie.tile(2, 4) + %t34 = aie.tile(3, 4) + aie.cascade_flow(%t14, %t24) + aie.cascade_flow(%t24, %t34) + } +} From 98d71aa050303ef6e33712affc9dbcd85c8a2f9f Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 14 Feb 2024 07:55:35 -0700 Subject: [PATCH 43/51] Enable cascade lowering in aiecc --- python/compiler/aiecc/main.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/python/compiler/aiecc/main.py b/python/compiler/aiecc/main.py index fbc2d12931..b8cee6e67f 100644 --- a/python/compiler/aiecc/main.py +++ b/python/compiler/aiecc/main.py @@ -47,6 +47,7 @@ .add_pass("aie-assign-lock-ids") .add_pass("aie-register-objectFifos") .add_pass("aie-objectFifo-stateful-transform") + .add_pass("aie-lower-cascade-flows") .add_pass("aie-lower-broadcast-packet") .add_pass("aie-create-packet-flows") .add_pass("aie-lower-multicast") @@ -970,6 +971,7 @@ async def run_flow(self): "aie.device(" + "aie-assign-lock-ids", "aie-register-objectFifos", "aie-objectFifo-stateful-transform", + "aie-lower-cascade-flows", "aie-lower-broadcast-packet", "aie-create-packet-flows", "aie-lower-multicast", From 9964026f3a5e665b5e8d699d556291b9c2c9a23d Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 14 Feb 2024 07:57:02 -0700 Subject: [PATCH 44/51] Rename cascade ipu test --- .../ipu-xrt/{configure_cascade => cascade_flows}/CMakeLists.txt | 0 test/ipu-xrt/{configure_cascade => cascade_flows}/Makefile | 2 +- test/ipu-xrt/{configure_cascade => cascade_flows}/aie.mlir | 0 test/ipu-xrt/{configure_cascade => cascade_flows}/kernel1.cc | 0 test/ipu-xrt/{configure_cascade => cascade_flows}/kernel2.cc | 0 test/ipu-xrt/{configure_cascade => cascade_flows}/kernel3.cc | 0 test/ipu-xrt/{configure_cascade => cascade_flows}/run.lit | 0 test/ipu-xrt/{configure_cascade => cascade_flows}/test.cpp | 0 8 files changed, 1 insertion(+), 1 deletion(-) rename test/ipu-xrt/{configure_cascade => cascade_flows}/CMakeLists.txt (100%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/Makefile (97%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/aie.mlir (100%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/kernel1.cc (100%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/kernel2.cc (100%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/kernel3.cc (100%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/run.lit (100%) rename test/ipu-xrt/{configure_cascade => cascade_flows}/test.cpp (100%) diff --git a/test/ipu-xrt/configure_cascade/CMakeLists.txt b/test/ipu-xrt/cascade_flows/CMakeLists.txt similarity index 100% rename from test/ipu-xrt/configure_cascade/CMakeLists.txt rename to test/ipu-xrt/cascade_flows/CMakeLists.txt diff --git a/test/ipu-xrt/configure_cascade/Makefile b/test/ipu-xrt/cascade_flows/Makefile similarity index 97% rename from test/ipu-xrt/configure_cascade/Makefile rename to test/ipu-xrt/cascade_flows/Makefile index e7cebe90a1..9618c5ad64 100644 --- a/test/ipu-xrt/configure_cascade/Makefile +++ b/test/ipu-xrt/cascade_flows/Makefile @@ -8,7 +8,7 @@ include ../makefile-common -targetname = configureCascade +targetname = cascadeFlows all: build/final.xclbin build/insts.txt diff --git a/test/ipu-xrt/configure_cascade/aie.mlir b/test/ipu-xrt/cascade_flows/aie.mlir similarity index 100% rename from test/ipu-xrt/configure_cascade/aie.mlir rename to test/ipu-xrt/cascade_flows/aie.mlir diff --git a/test/ipu-xrt/configure_cascade/kernel1.cc b/test/ipu-xrt/cascade_flows/kernel1.cc similarity index 100% rename from test/ipu-xrt/configure_cascade/kernel1.cc rename to test/ipu-xrt/cascade_flows/kernel1.cc diff --git a/test/ipu-xrt/configure_cascade/kernel2.cc b/test/ipu-xrt/cascade_flows/kernel2.cc similarity index 100% rename from test/ipu-xrt/configure_cascade/kernel2.cc rename to test/ipu-xrt/cascade_flows/kernel2.cc diff --git a/test/ipu-xrt/configure_cascade/kernel3.cc b/test/ipu-xrt/cascade_flows/kernel3.cc similarity index 100% rename from test/ipu-xrt/configure_cascade/kernel3.cc rename to test/ipu-xrt/cascade_flows/kernel3.cc diff --git a/test/ipu-xrt/configure_cascade/run.lit b/test/ipu-xrt/cascade_flows/run.lit similarity index 100% rename from test/ipu-xrt/configure_cascade/run.lit rename to test/ipu-xrt/cascade_flows/run.lit diff --git a/test/ipu-xrt/configure_cascade/test.cpp b/test/ipu-xrt/cascade_flows/test.cpp similarity index 100% rename from test/ipu-xrt/configure_cascade/test.cpp rename to test/ipu-xrt/cascade_flows/test.cpp From 2adebaf8a556e7e260bb721e50633e452dd982c8 Mon Sep 17 00:00:00 2001 From: abisca Date: Wed, 14 Feb 2024 08:26:02 -0700 Subject: [PATCH 45/51] Rename test target --- test/ipu-xrt/cascade_flows/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ipu-xrt/cascade_flows/Makefile b/test/ipu-xrt/cascade_flows/Makefile index 9618c5ad64..6c88c72d19 100644 --- a/test/ipu-xrt/cascade_flows/Makefile +++ b/test/ipu-xrt/cascade_flows/Makefile @@ -30,7 +30,7 @@ ifeq "${powershell}" "powershell.exe" cp _build/${targetname}.exe $@ else cp _build/${targetname} $@ -endif +endif run: ${targetname}.exe build/final.xclbin build/insts.txt ${powershell} ./$< -x build/final.xclbin -i build/insts.txt -k MLIR_AIE From 8b8041fbccb0d11969c9ac1d2f085b374750c85d Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 15 Feb 2024 06:21:50 -0700 Subject: [PATCH 46/51] Replace CascadeSwitchboxOp with previously deprecated ConfigureCascadeOp. Update lowerings and tests. --- include/aie/Dialect/AIE/IR/AIEAttrs.td | 8 +++ include/aie/Dialect/AIE/IR/AIEOps.td | 43 +++++------- lib/Dialect/AIE/IR/AIEDialect.cpp | 61 +++++------------ .../AIE/Transforms/AIECoreToStandard.cpp | 2 +- .../AIE/Transforms/AIELowerCascadeFlows.cpp | 25 ++----- lib/Targets/AIETargetAirbin.cpp | 47 ++++++-------- lib/Targets/AIETargetCDODirect.cpp | 22 +++---- lib/Targets/AIETargetXAIEV2.cpp | 19 ++---- ..._flow.mlir => aie2_configure_cascade.mlir} | 19 ++---- test/dialect/AIE/bad_cascade.mlir | 65 ++----------------- test/dialect/AIE/configure_cascade.mlir | 20 ++++++ .../cascade_single_flow.mlir | 16 ++--- .../cascade_two_flows.mlir | 12 +--- 13 files changed, 120 insertions(+), 239 deletions(-) rename test/Targets/AIEGenerateXAIE/{aie2_cascade_flow.mlir => aie2_configure_cascade.mlir} (68%) create mode 100644 test/dialect/AIE/configure_cascade.mlir diff --git a/include/aie/Dialect/AIE/IR/AIEAttrs.td b/include/aie/Dialect/AIE/IR/AIEAttrs.td index 932005919a..4d2f17371f 100644 --- a/include/aie/Dialect/AIE/IR/AIEAttrs.td +++ b/include/aie/Dialect/AIE/IR/AIEAttrs.td @@ -59,6 +59,14 @@ def WireBundle: I32EnumAttr<"WireBundle", "Bundle of wires", 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>, diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index fe2d158ff1..7bf17837e6 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -369,7 +369,7 @@ def AIE_PLIOOp: AIE_Op<"plio", [ }]; } -def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp", "CascadeSwitchboxOp"]> ]> { +def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp"]> ]> { let arguments = ( ins WireBundle:$source_bundle, ConfinedAttr]>:$source_channel, @@ -380,7 +380,7 @@ def AIE_ConnectOp: AIE_Op<"connect", [ParentOneOf<["SwitchboxOp", "ShimMuxOp", " 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` or `aie.cascade_switchbox` operation. + 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. @@ -1371,38 +1371,27 @@ def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { }]; } -def AIE_CascadeSwitchboxOp: AIE_Op<"cascade_switchbox", [ - TileElement, - SingleBlockImplicitTerminator<"EndOp">, - DeclareOpInterfaceMethods - ]>, Results<(outs Index:$result)> { - let arguments = (ins Index:$tile); - - let summary = "Declare a cascade switch"; +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 = [{ - This operation represents a switchbox which contans the programmed input and output directions - for the cascade streams on a tile. A switchbox is configured by code in its region, representing - various connections. + An operation to configure the cascade on a single tile in both the input and the output + directions. Example: ``` - %tile = aie.tile(1, 1) - aie.cascade_switchbox(%tile) { - aie.connect<"West" : 0, "East" : 0> - } + %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 regions = (region AnyRegion:$connections); - let assemblyFormat = [{ `(` $tile `)` regions attr-dict }]; + let arguments = ( + ins Index:$tile, + CascadeDir:$inputDir, + CascadeDir:$outputDir + ); + let results = (outs); let hasVerifier = 1; - - let extraClassDeclaration = [{ - int colIndex(); - int rowIndex(); - TileOp getTileOp(); - using ::xilinx::AIE::TileElement::Trait::getAsmResultNames; - }]; + let assemblyFormat = [{ `(` $tile `,` $inputDir `,` $outputDir `)` attr-dict }]; } def AIE_GetCascadeOp: AIE_Op<"get_cascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascade_value)> { diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index e620370d23..9ac64bdee5 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -897,59 +897,30 @@ TileOp CascadeFlowOp::getDestTileOp() { } //===----------------------------------------------------------------------===// -// CascadeSwitchboxOp +// ConfigureCascadeOp //===----------------------------------------------------------------------===// -LogicalResult CascadeSwitchboxOp::verify() { +LogicalResult ConfigureCascadeOp::verify() { const auto &targetModel = getTargetModel(*this); - Region &body = getConnections(); - if (body.empty()) - return emitOpError("should have non-empty body"); - if (getTileOp().isShimTile()) - return emitOpError("shimTile row has no cascade stream interface"); - if (targetModel.isMemTile(colIndex(), rowIndex())) - return emitOpError("memTile row has no cascade stream interface"); - - int numOp = 0; - for (auto &ops : body.front()) { - if (auto connectOp = dyn_cast(ops)) { - numOp++; - WireBundle inDir = connectOp.getSourceBundle(); - if (inDir != WireBundle::West && inDir != WireBundle::North) { - return connectOp.emitOpError( - "source port of ConnectOp in CascadeSwitchboxOp must be West or " - "North"); - } - WireBundle outDir = connectOp.getDestBundle(); - if (outDir != WireBundle::East && outDir != WireBundle::South) { - return connectOp.emitOpError( - "dest port of ConnectOp in CascadeSwitchboxOp must be East or " - "South"); - } - if (connectOp.sourceIndex() != 0 || connectOp.destIndex() != 0) { - return connectOp.emitOpError("portIndex of ConnectOp is out-of-bounds"); - } - } else if (isa(ops)) { - // continue; - } else { - return ops.emitOpError("cannot be contained in a CascadeSwitchboxOp"); + CascadeDir inputDir = getInputDir(); + CascadeDir outputDir = getOutputDir(); + if (targetModel.getTargetArch() == AIEArch::AIE2) { + if (inputDir == CascadeDir::South || inputDir == CascadeDir::East) { + return emitOpError("input direction of cascade must be North or West on ") + << stringifyAIEArch(targetModel.getTargetArch()); } - } - if (numOp > 1) { - return emitOpError( - "cannot have more than one ConnectOp in CascadeSwitchboxOp"); + if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { + return emitOpError( + "output direction of cascade must be South or East on ") + << stringifyAIEArch(targetModel.getTargetArch()); + } + } else { + return emitOpError("cascade not supported in ") + << stringifyAIEArch(targetModel.getTargetArch()); } return success(); } -int CascadeSwitchboxOp::colIndex() { return getTileOp().colIndex(); } - -int CascadeSwitchboxOp::rowIndex() { return getTileOp().rowIndex(); } - -TileOp CascadeSwitchboxOp::getTileOp() { - return cast(getTile().getDefiningOp()); -} - //===----------------------------------------------------------------------===// // PutCascadeOp //===----------------------------------------------------------------------===// diff --git a/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp b/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp index 21bf446a1d..1276ac8e68 100644 --- a/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp +++ b/lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp @@ -571,7 +571,7 @@ struct AIECoreToStandardPass : AIECoreToStandardBase { AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, AIEOpRemoval, - AIEOpRemoval, AIEOpRemoval>( + AIEOpRemoval, AIEOpRemoval>( m.getContext(), m); if (failed(applyPartialConversion(m, target, std::move(removepatterns)))) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index ca56ba2a1b..8925b5474d 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -22,16 +22,6 @@ using namespace mlir; using namespace xilinx; using namespace xilinx::AIE; -CascadeSwitchboxOp getOrCreateCascadeSwitchbox(OpBuilder &builder, - TileOp tile) { - for (auto i : tile.getResult().getUsers()) { - if (llvm::isa(*i)) { - return llvm::cast(*i); - } - } - return builder.create(builder.getUnknownLoc(), tile); -} - struct AIELowerCascadeFlowsPass : AIELowerCascadeFlowsBase { void getDependentDialects(DialectRegistry ®istry) const override { @@ -70,14 +60,8 @@ struct AIELowerCascadeFlowsPass } } - // generate cascade switchboxes + // generate configure cascade ops for (TileOp tile : tilesWithCascadeFlow) { - CascadeSwitchboxOp swbox = getOrCreateCascadeSwitchbox(builder, tile); - CascadeSwitchboxOp::ensureTerminator(swbox.getConnections(), builder, - builder.getUnknownLoc()); - Block &b = swbox.getConnections().front(); - builder.setInsertionPoint(b.getTerminator()); - WireBundle inputDir; if (cascadeInputsPerTile.find(tile) != cascadeInputsPerTile.end()) { inputDir = cascadeInputsPerTile[tile]; @@ -90,10 +74,9 @@ struct AIELowerCascadeFlowsPass } else { outputDir = WireBundle::South; } - int channelIndex = 0; - builder.create(builder.getUnknownLoc(), inputDir, channelIndex, - outputDir, channelIndex); - builder.setInsertionPointAfter(swbox); + builder.create(builder.getUnknownLoc(), tile, + static_cast(inputDir), + static_cast(outputDir)); } // erase CascadeFlowOps diff --git a/lib/Targets/AIETargetAirbin.cpp b/lib/Targets/AIETargetAirbin.cpp index ad1f9cbc35..6c78a00ed3 100644 --- a/lib/Targets/AIETargetAirbin.cpp +++ b/lib/Targets/AIETargetAirbin.cpp @@ -1064,33 +1064,26 @@ static void configureSwitchBoxes(DeviceOp &targetOp) { static void configureCascade(DeviceOp &targetOp) { const auto &target_model = xilinx::AIE::getTargetModel(targetOp); if (target_model.getTargetArch() == AIEArch::AIE2) { - for (auto cascadeSwboxOp : targetOp.getOps()) { - TileOp tile = cascadeSwboxOp.getTileOp(); - Region &body = cascadeSwboxOp.getConnections(); - for (auto &ops : body.front()) { - if (auto connectOp = dyn_cast(ops)) { - auto inputDir = - stringifyWireBundle(connectOp.getSourceBundle()).upper(); - auto outputDir = - stringifyWireBundle(connectOp.getDestBundle()).upper(); - - Address address{tile, 0x36060u}; - - /* - * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST - * * Register value for input BIT 0: 0 == NORTH, 1 == WEST - */ - uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; - uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; - - constexpr Field<1> Output; - constexpr Field<0> Input; - - auto regValue = Output(outputValue) | Input(inputValue); - - write32(address, regValue); - } - } + for (auto configOp : targetOp.getOps()) { + TileOp tile = cast(configOp.getTile().getDefiningOp()); + auto inputDir = stringifyCascadeDir(configOp.getInputDir()).upper(); + auto outputDir = stringifyCascadeDir(configOp.getOutputDir()).upper(); + + Address address{tile, 0x36060u}; + + /* + * * Register value for output BIT 1: 0 == SOUTH, 1 == EAST + * * Register value for input BIT 0: 0 == NORTH, 1 == WEST + */ + uint8_t outputValue = (outputDir == "SOUTH") ? 0 : 1; + uint8_t inputValue = (inputDir == "NORTH") ? 0 : 1; + + constexpr Field<1> Output; + constexpr Field<0> Input; + + auto regValue = Output(outputValue) | Input(inputValue); + + write32(address, regValue); } } } diff --git a/lib/Targets/AIETargetCDODirect.cpp b/lib/Targets/AIETargetCDODirect.cpp index 0e767c18d9..5a10d4b1f9 100644 --- a/lib/Targets/AIETargetCDODirect.cpp +++ b/lib/Targets/AIETargetCDODirect.cpp @@ -704,19 +704,15 @@ struct AIEControl { // Cascade configuration const auto &target_model = xilinx::AIE::getTargetModel(targetOp); if (target_model.getTargetArch() == AIEArch::AIE2) { - for (auto cascadeSwboxOp : targetOp.getOps()) { - TileOp tile = cascadeSwboxOp.getTileOp(); - Region &body = cascadeSwboxOp.getConnections(); - for (auto &ops : body.front()) { - if (auto connectOp = dyn_cast(ops)) { - auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); - TRY_XAIE_API_EMIT_ERROR( - targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( - connectOp.getSourceBundle()), - WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at(connectOp.getDestBundle())); - } - } + for (auto configOp : targetOp.getOps()) { + TileOp tile = cast(configOp.getTile().getDefiningOp()); + auto tileLoc = XAie_TileLoc(tile.getCol(), tile.getRow()); + TRY_XAIE_API_EMIT_ERROR( + targetOp, XAie_CoreConfigAccumulatorControl, &devInst, tileLoc, + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + static_cast(configOp.getInputDir())), + WIRE_BUNDLE_TO_STRM_SW_PORT_TYPE.at( + static_cast(configOp.getOutputDir()))); } } diff --git a/lib/Targets/AIETargetXAIEV2.cpp b/lib/Targets/AIETargetXAIEV2.cpp index ee6914b101..11b0e1c424 100644 --- a/lib/Targets/AIETargetXAIEV2.cpp +++ b/lib/Targets/AIETargetXAIEV2.cpp @@ -769,21 +769,14 @@ mlir::LogicalResult AIETranslateToXAIEV2(ModuleOp module, raw_ostream &output) { // mlir_aie_configure_cascade //--------------------------------------------------------------------------- output << "int mlir_aie_configure_cascade(" << ctx_p << ") {\n"; - for (auto cascadeSwboxOp : targetOp.getOps()) { - TileOp tile = cascadeSwboxOp.getTileOp(); + for (auto configOp : targetOp.getOps()) { + TileOp tile = cast(configOp.getTile().getDefiningOp()); int col = tile.colIndex(); int row = tile.rowIndex(); - Region &body = cascadeSwboxOp.getConnections(); - for (auto &ops : body.front()) { - if (auto connectOp = dyn_cast(ops)) { - WireBundle inputDir = connectOp.getSourceBundle(); - WireBundle outputDir = connectOp.getDestBundle(); - output << "XAie_CoreConfigAccumulatorControl(" << deviceInstRef << ", " - << "XAie_TileLoc(" << col << ", " << row << "), " - << stringifyWireBundle(inputDir).upper() << ", " - << stringifyWireBundle(outputDir).upper() << ");\n"; - } - } + output << "XAie_CoreConfigAccumulatorControl(" << deviceInstRef << ", " + << "XAie_TileLoc(" << col << ", " << row << "), " + << stringifyCascadeDir(configOp.getInputDir()).upper() << ", " + << stringifyCascadeDir(configOp.getOutputDir()).upper() << ");\n"; } output << "return XAIE_OK;\n"; output << "} // mlir_aie_configure_cascade\n\n"; diff --git a/test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir b/test/Targets/AIEGenerateXAIE/aie2_configure_cascade.mlir similarity index 68% rename from test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir rename to test/Targets/AIEGenerateXAIE/aie2_configure_cascade.mlir index 45360a9e9a..7ed2bf4afc 100644 --- a/test/Targets/AIEGenerateXAIE/aie2_cascade_flow.mlir +++ b/test/Targets/AIEGenerateXAIE/aie2_configure_cascade.mlir @@ -1,4 +1,4 @@ -//===- aie2_cascade_flow.mlir -----------------------------------*- MLIR -*-===// +//===- aie2_configure_cascade.mlir ------------------------------*- MLIR -*-===// // // This file is licensed under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -24,17 +24,10 @@ module @cascade_flow { %tile_2_3 = aie.tile(2, 3) %tile_3_4 = aie.tile(3, 4) %tile_3_3 = aie.tile(3, 3) - %cascade_switchbox_1_3 = aie.cascade_switchbox(%tile_1_3) { - aie.connect - } - %cascade_switchbox_2_3 = aie.cascade_switchbox(%tile_2_3) { - aie.connect - } - %cascade_switchbox_3_4 = aie.cascade_switchbox(%tile_3_4) { - aie.connect - } - %cascade_switchbox_3_3 = aie.cascade_switchbox(%tile_3_3) { - aie.connect - } + + aie.configure_cascade(%tile_1_3, North, East) + aie.configure_cascade(%tile_2_3, West, South) + aie.configure_cascade(%tile_3_4, North, South) + aie.configure_cascade(%tile_3_3, North, South) } } diff --git a/test/dialect/AIE/bad_cascade.mlir b/test/dialect/AIE/bad_cascade.mlir index 56041cf82b..cb6c7bb478 100644 --- a/test/dialect/AIE/bad_cascade.mlir +++ b/test/dialect/AIE/bad_cascade.mlir @@ -49,78 +49,27 @@ aie.device(ipu) { // ----- -// CHECK: error{{.*}}'aie.cascade_switchbox' op memTile row has no cascade stream interface - -aie.device(xcve2802) { - %t12 = aie.tile(1, 2) - aie.cascade_switchbox(%t12) { - aie.connect - } -} - -// ----- - -// CHECK: error{{.*}}'aie.cascade_switchbox' op shimTile row has no cascade stream interface - -aie.device(ipu) { - %t10 = aie.tile(1, 0) - aie.cascade_switchbox(%t10) { - aie.connect - } -} - -// ----- - -// CHECK: error{{.*}}'aie.cascade_switchbox' op memTile row has no cascade stream interface - -aie.device(ipu) { - %t11 = aie.tile(1, 1) - aie.cascade_switchbox(%t11) { - aie.connect - } -} - -// ----- - -// CHECK: error{{.*}}'aie.cascade_switchbox' op cannot have more than one ConnectOp in CascadeSwitchboxOp - -aie.device(xcve2802) { - %t13 = aie.tile(1, 3) - aie.cascade_switchbox(%t13) { - aie.connect - aie.connect - } -} - -// ----- - -// CHECK: error{{.*}}'aie.connect' op portIndex of ConnectOp is out-of-bounds +// CHECK: error{{.*}}'aie.configure_cascade' op input direction of cascade must be North or West on AIE2 aie.device(xcve2802) { %t13 = aie.tile(1, 3) - aie.cascade_switchbox(%t13) { - aie.connect - } + aie.configure_cascade(%t13, East, South) } // ----- -// CHECK: error{{.*}}'aie.connect' op source port of ConnectOp in CascadeSwitchboxOp must be West or North +// CHECK: error{{.*}}'aie.configure_cascade' op output direction of cascade must be South or East on AIE2 aie.device(xcve2802) { %t13 = aie.tile(1, 3) - aie.cascade_switchbox(%t13) { - aie.connect - } + aie.configure_cascade(%t13, North, West) } // ----- -// CHECK: error{{.*}}'aie.connect' op dest port of ConnectOp in CascadeSwitchboxOp must be East or South +// CHECK: error{{.*}}'aie.configure_cascade' op cascade not supported in AIE1 -aie.device(xcve2802) { +aie.device(xcvc1902) { %t13 = aie.tile(1, 3) - aie.cascade_switchbox(%t13) { - aie.connect - } + aie.configure_cascade(%t13, North, East) } diff --git a/test/dialect/AIE/configure_cascade.mlir b/test/dialect/AIE/configure_cascade.mlir new file mode 100644 index 0000000000..2fa51fe137 --- /dev/null +++ b/test/dialect/AIE/configure_cascade.mlir @@ -0,0 +1,20 @@ +//===- configure_cascade.mlir -----------------------------------*- MLIR -*-===// +// +// 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 2024 Advanced Micro Devices, Inc. +// +//===----------------------------------------------------------------------===// + +// RUN: aie-opt %s + +module @test { + aie.device(xcve2802) { + %t13 = aie.tile(1, 3) + %t23 = aie.tile(2, 3) + aie.configure_cascade(%t13, North, West) + aie.configure_cascade(%t23, East, South) + } +} diff --git a/test/lower-cascade-flows/cascade_single_flow.mlir b/test/lower-cascade-flows/cascade_single_flow.mlir index 92d4d60688..708108aacc 100644 --- a/test/lower-cascade-flows/cascade_single_flow.mlir +++ b/test/lower-cascade-flows/cascade_single_flow.mlir @@ -16,18 +16,10 @@ // CHECK: %tile_2_3 = aie.tile(2, 3) // CHECK: %tile_3_4 = aie.tile(3, 4) // CHECK: %tile_3_3 = aie.tile(3, 3) -// CHECK: %cascade_switchbox_1_3 = aie.cascade_switchbox(%tile_1_3) { -// CHECK: aie.connect -// CHECK: } -// CHECK: %cascade_switchbox_2_3 = aie.cascade_switchbox(%tile_2_3) { -// CHECK: aie.connect -// CHECK: } -// CHECK: %cascade_switchbox_3_4 = aie.cascade_switchbox(%tile_3_4) { -// CHECK: aie.connect -// CHECK: } -// CHECK: %cascade_switchbox_3_3 = aie.cascade_switchbox(%tile_3_3) { -// CHECK: aie.connect -// CHECK: } +// CHECK: aie.configure_cascade(%tile_1_3, North, East) +// CHECK: aie.configure_cascade(%tile_2_3, West, South) +// CHECK: aie.configure_cascade(%tile_3_4, North, South) +// CHECK: aie.configure_cascade(%tile_3_3, North, South) // CHECK: } // CHECK: } diff --git a/test/lower-cascade-flows/cascade_two_flows.mlir b/test/lower-cascade-flows/cascade_two_flows.mlir index 79f3be4f40..b61a82238a 100644 --- a/test/lower-cascade-flows/cascade_two_flows.mlir +++ b/test/lower-cascade-flows/cascade_two_flows.mlir @@ -15,15 +15,9 @@ // CHECK: %tile_1_4 = aie.tile(1, 4) // CHECK: %tile_2_4 = aie.tile(2, 4) // CHECK: %tile_3_4 = aie.tile(3, 4) -// CHECK: %cascade_switchbox_1_4 = aie.cascade_switchbox(%tile_1_4) { -// CHECK: aie.connect -// CHECK: } -// CHECK: %cascade_switchbox_2_4 = aie.cascade_switchbox(%tile_2_4) { -// CHECK: aie.connect -// CHECK: } -// CHECK: %cascade_switchbox_3_4 = aie.cascade_switchbox(%tile_3_4) { -// CHECK: aie.connect -// CHECK: } +// CHECK: aie.configure_cascade(%tile_1_4, North, East) +// CHECK: aie.configure_cascade(%tile_2_4, West, East) +// CHECK: aie.configure_cascade(%tile_3_4, West, South) // CHECK: } // CHECK: } From ecc276b71f280c554ccfb0296093d25abfbfd01b Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 15 Feb 2024 06:49:07 -0700 Subject: [PATCH 47/51] Add extra tile checks to ConfigureCascadeOp verify() --- lib/Dialect/AIE/IR/AIEDialect.cpp | 17 ++++++++++++----- test/dialect/AIE/bad_cascade.mlir | 18 ++++++++++++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/lib/Dialect/AIE/IR/AIEDialect.cpp b/lib/Dialect/AIE/IR/AIEDialect.cpp index 9ac64bdee5..2a61307a46 100644 --- a/lib/Dialect/AIE/IR/AIEDialect.cpp +++ b/lib/Dialect/AIE/IR/AIEDialect.cpp @@ -901,22 +901,29 @@ TileOp CascadeFlowOp::getDestTileOp() { //===----------------------------------------------------------------------===// LogicalResult ConfigureCascadeOp::verify() { - const auto &targetModel = getTargetModel(*this); + const auto &t = getTargetModel(*this); + TileOp tile = cast(getTile().getDefiningOp()); CascadeDir inputDir = getInputDir(); CascadeDir outputDir = getOutputDir(); - if (targetModel.getTargetArch() == AIEArch::AIE2) { + + 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(targetModel.getTargetArch()); + << stringifyAIEArch(t.getTargetArch()); } if (outputDir == CascadeDir::North || outputDir == CascadeDir::West) { return emitOpError( "output direction of cascade must be South or East on ") - << stringifyAIEArch(targetModel.getTargetArch()); + << stringifyAIEArch(t.getTargetArch()); } } else { return emitOpError("cascade not supported in ") - << stringifyAIEArch(targetModel.getTargetArch()); + << stringifyAIEArch(t.getTargetArch()); } return success(); } diff --git a/test/dialect/AIE/bad_cascade.mlir b/test/dialect/AIE/bad_cascade.mlir index cb6c7bb478..21adc09a48 100644 --- a/test/dialect/AIE/bad_cascade.mlir +++ b/test/dialect/AIE/bad_cascade.mlir @@ -73,3 +73,21 @@ aie.device(xcvc1902) { %t13 = aie.tile(1, 3) aie.configure_cascade(%t13, North, East) } + +// ----- + +// CHECK: error{{.*}}'aie.configure_cascade' op shimTile row has no cascade stream interface + +aie.device(xcve2802) { + %t10 = aie.tile(1, 0) + aie.configure_cascade(%t10, North, West) +} + +// ----- + +// CHECK: error{{.*}}'aie.configure_cascade' op memTile row has no cascade stream interface + +aie.device(ipu) { + %t11 = aie.tile(1, 1) + aie.configure_cascade(%t11, North, West) +} From 59275b8868798c0544a5617dcfa13c73ad3ab1ff Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 15 Feb 2024 06:50:26 -0700 Subject: [PATCH 48/51] Add chess requirement to test --- test/ipu-xrt/cascade_flows/run.lit | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/ipu-xrt/cascade_flows/run.lit b/test/ipu-xrt/cascade_flows/run.lit index 4c4b1347a1..6581a3a212 100644 --- a/test/ipu-xrt/cascade_flows/run.lit +++ b/test/ipu-xrt/cascade_flows/run.lit @@ -1,7 +1,7 @@ // (c) Copyright 2024 Advanced Micro Devices, Inc. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // -// REQUIRES: ryzen_ai +// REQUIRES: ryzen_ai, chess // // RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel1.cc -o ./kernel1.o // RUN: xchesscc_wrapper aie2 -I %aietools/include -c %S/kernel2.cc -o ./kernel2.o From faf0c51928eed155eb3edf9a772a5cf33351f54c Mon Sep 17 00:00:00 2001 From: Andra Bisca Date: Thu, 15 Feb 2024 14:52:44 +0100 Subject: [PATCH 49/51] Update lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp index 8925b5474d..0aefec1e4c 100644 --- a/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp +++ b/lib/Dialect/AIE/Transforms/AIELowerCascadeFlows.cpp @@ -74,7 +74,7 @@ struct AIELowerCascadeFlowsPass } else { outputDir = WireBundle::South; } - builder.create(builder.getUnknownLoc(), tile, + builder.create(builder.getUnknownLoc(), tile, static_cast(inputDir), static_cast(outputDir)); } From 5d31e2335c8fee0309e0a046c92e9e5e9544f6b3 Mon Sep 17 00:00:00 2001 From: abisca Date: Thu, 15 Feb 2024 07:00:45 -0700 Subject: [PATCH 50/51] Test fix --- test/dialect/AIE/configure_cascade.mlir | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/dialect/AIE/configure_cascade.mlir b/test/dialect/AIE/configure_cascade.mlir index 2fa51fe137..c0ffd0d219 100644 --- a/test/dialect/AIE/configure_cascade.mlir +++ b/test/dialect/AIE/configure_cascade.mlir @@ -14,7 +14,7 @@ module @test { aie.device(xcve2802) { %t13 = aie.tile(1, 3) %t23 = aie.tile(2, 3) - aie.configure_cascade(%t13, North, West) - aie.configure_cascade(%t23, East, South) + aie.configure_cascade(%t13, North, East) + aie.configure_cascade(%t23, West, South) } } From f03ae645029d5585c99090de38da3245209adba0 Mon Sep 17 00:00:00 2001 From: AndraBisca Date: Mon, 19 Feb 2024 08:33:08 -0700 Subject: [PATCH 51/51] Update .td descriptions of ops --- include/aie/Dialect/AIE/IR/AIEOps.td | 4 ++-- include/aie/Dialect/AIE/Transforms/AIEPasses.td | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/include/aie/Dialect/AIE/IR/AIEOps.td b/include/aie/Dialect/AIE/IR/AIEOps.td index cf657add5e..ff71988a79 100644 --- a/include/aie/Dialect/AIE/IR/AIEOps.td +++ b/include/aie/Dialect/AIE/IR/AIEOps.td @@ -1353,8 +1353,8 @@ def AIE_CascadeFlowOp: AIE_Op<"cascade_flow", []> { let summary = "A cascade connection between tiles"; let description = [{ The `aie.cascade_flow` operation represents a cascade connection between two `aie.tile` operations. - During routing, this is replaced by `aie.connect` operations which represent the programmed connections - inside an `aie.cascade_switchbox`. + During lowering, this is replaced by `aie.configure_cascade` operations for each `aie.tile` based on + their relative placement to one another. Example: ``` diff --git a/include/aie/Dialect/AIE/Transforms/AIEPasses.td b/include/aie/Dialect/AIE/Transforms/AIEPasses.td index 9f5a45347b..775c46dd21 100644 --- a/include/aie/Dialect/AIE/Transforms/AIEPasses.td +++ b/include/aie/Dialect/AIE/Transforms/AIEPasses.td @@ -212,9 +212,9 @@ def AIEObjectFifoRegisterProcess : Pass<"aie-register-objectFifos", "DeviceOp"> } def AIELowerCascadeFlows : Pass<"aie-lower-cascade-flows", "DeviceOp"> { - let summary = "Lower aie.cascade_flow operations through cascade switchboxes"; + let summary = "Lower aie.cascade_flow operations through `aie.configure_cascade` operations"; let description = [{ - Replace each aie.cascade_flow operation with an equivalent set of aie.cascade_switchbox + Replace each aie.cascade_flow operation with an equivalent set of `aie.configure_cascade` operations. }];