Skip to content
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
a61bdd1
Allow multiple devices with names; refactorings
andrej Aug 22, 2025
415dd91
fixes 1
andrej Aug 22, 2025
5ef4d24
fixes 2
andrej Aug 22, 2025
ddf1615
fixes 3
andrej Aug 22, 2025
22cfe40
change to region-based syntax and add some tests
andrej Aug 22, 2025
6c1f28c
fixes 4
andrej Aug 22, 2025
22f76f5
fixes 5
andrej Aug 22, 2025
b5ab950
fix one million
andrej Aug 27, 2025
473bbef
oops
andrej Aug 27, 2025
deb46ee
fix one million and one
andrej Aug 27, 2025
6d261d1
Merge branch 'main' into reconfig-clean
andrej Aug 27, 2025
3aca900
fix one million and two
andrej Aug 27, 2025
aa9ccdb
fixes one million and three
andrej Aug 27, 2025
e85e889
fix one million and five
andrej Aug 27, 2025
102a00e
that was dumb
andrej Aug 27, 2025
2741ca5
Merge branch 'main' into reconfig-clean
andrej Sep 16, 2025
65065d6
fix progress bar error
andrej Sep 17, 2025
b1f7934
add device to tests without device
andrej Sep 18, 2025
1e428de
fixes
andrej Sep 19, 2025
991bc3b
fix localize locks to only add locks when core uses them
andrej Sep 22, 2025
19dd016
clang-format/black
andrej Sep 22, 2025
551b043
replace set-elf-for-core pass with code in aiecc.py main
andrej Sep 22, 2025
272ead7
make which device to compile configurable for AIEToConfiguration lowe…
andrej Sep 23, 2025
e016165
refactor add_one_two test to use multiple devices in same file
andrej Sep 23, 2025
71df8a1
make 'main' the default device, instead of picking first device found…
andrej Sep 23, 2025
52dc724
address Andra's comments
andrej Sep 23, 2025
0088ed6
clang-format/black
andrej Sep 23, 2025
9063ade
clang-format seventeen
andrej Sep 24, 2025
dd1e206
Merge branch 'main' into reconfig-clean
andrej Sep 25, 2025
ec9add7
address Jeff's comments
andrej Sep 26, 2025
988fd88
Merge branch 'main' into reconfig-clean
andrej Sep 26, 2025
deff8c3
clang format
andrej Sep 26, 2025
08f611d
make sure tests regenerate JIT cache
andrej Sep 30, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion docs/buildHostLin.md
Original file line number Diff line number Diff line change
Expand Up @@ -403,7 +403,7 @@ For your design of interest, for instance from [programming_examples](../program
1. Run (program arguments are just an example for add_one design)
```bash
cd Release
.\<testName>.exe -x ..\..\build\final.xclbin -k MLIR_AIE -i ..\..\build\insts.txt -v 1
.\<testName>.exe -x ..\..\build\main.xclbin -k MLIR_AIE -i ..\..\build\main_sequence.bin -v 1
```

# Troubleshooting
Expand Down
15 changes: 9 additions & 6 deletions include/aie-c/Translation.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ MLIR_CAPI_EXPORTED MlirStringRef aieTranslateAIEVecToCpp(MlirOperation op,
bool aie2);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateModuleToLLVMIR(MlirOperation op);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateNpuToBinary(MlirOperation op,
MlirStringRef name);
MlirStringRef deviceName,
MlirStringRef sequenceName);
MLIR_CAPI_EXPORTED MlirStringRef
aieTranslateControlPacketsToUI32Vec(MlirOperation op);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateToXAIEV2(MlirOperation op);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateToHSA(MlirOperation op);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateToBCF(MlirOperation op, int col,
int row);
aieTranslateControlPacketsToUI32Vec(MlirOperation op, MlirStringRef deviceName);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateToXAIEV2(MlirOperation op, MlirStringRef deviceName);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateToHSA(MlirOperation op, MlirStringRef deviceName);
MLIR_CAPI_EXPORTED MlirStringRef aieTranslateToBCF(MlirOperation op,
int col, int row,
MlirStringRef deviceName);
MLIR_CAPI_EXPORTED MlirStringRef aieLLVMLink(MlirStringRef *modules,
int nModules);
MLIR_CAPI_EXPORTED MlirLogicalResult
aieTranslateToCDODirect(MlirOperation moduleOp, MlirStringRef workDirPath,
MlirStringRef deviceName,
bool bigEndian, bool emitUnified, bool cdoDebug,
bool aieSim, bool xaieDebug, bool enableCores);
MLIR_CAPI_EXPORTED MlirOperation aieTranslateBinaryToTxn(MlirContext ctx,
Expand Down
2 changes: 2 additions & 0 deletions include/aie/Dialect/AIE/IR/AIEDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@
#include "mlir/IR/OpDefinition.h"
#include "mlir/IR/OpImplementation.h"

#include "llvm/ADT/StringRef.h"

namespace xilinx::AIE {

// Check that the given DMA-like op (e.g. MemOp, ShimDMAOp)
Expand Down
23 changes: 19 additions & 4 deletions include/aie/Dialect/AIE/IR/AIEOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,12 @@ class AIE_Op<string mnemonic, list<Trait> traits = []> :


def AIE_DeviceOp: AIE_Op<"device", [
AIETarget, HasParent<"mlir::ModuleOp">,
SymbolTable, SingleBlockImplicitTerminator<"EndOp">, IsolatedFromAbove
Symbol,
AIETarget,
HasParent<"mlir::ModuleOp">,
SymbolTable,
SingleBlockImplicitTerminator<"EndOp">,
IsolatedFromAbove
]> {
let summary = "Define an AIE design targetting a complete device";
let description = [{
Expand All @@ -55,13 +59,18 @@ def AIE_DeviceOp: AIE_Op<"device", [
```
}];

let arguments = (ins AIEDevice:$device);
let arguments = (
ins AIEDevice:$device,
DefaultValuedAttr<SymbolNameAttr, "\"main\"">:$sym_name
);
let regions = (region AnyRegion:$body_region);
let assemblyFormat = [{
`(` $device `)` regions attr-dict
`(` $device `)` ($sym_name^)? regions attr-dict
}];
let extraClassDeclaration = [{
const xilinx::AIE::AIETargetModel &getTargetModel();
static xilinx::AIE::DeviceOp getForSymbolInModule(mlir::ModuleOp module, llvm::StringRef symbol);
static xilinx::AIE::DeviceOp getForSymbolInModuleOrError(mlir::ModuleOp module, llvm::StringRef symbol);
}];
}

Expand Down Expand Up @@ -325,6 +334,11 @@ def AIE_CoreOp: AIE_Op<"core", [
for each core. The name of this file can be be specified using the `elf_file`
attribute.

If the `elf_file` attribute is present, no MLIR besides a terminator may be
present in the core; in that case, the binary file linked dictates what
will run in the core. The path specified should is relative to the MLIR
file.
Comment on lines +338 to +341
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does the presence of the attribute require that the core body is deleted? It seems to hard code things for the current aiecc use case.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought it would be more clear this way, removing the ambiguity of which code gets executed if both the attribute is there and there is code inside the body. If this complicates some use case I'm not aware of, I can remove this restriction.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have left this check in place for now. Let me know if you want to discuss it further.


This op has an optional `stackSize` attribute, to control the amount of memory (in bytes)
reserved for the stack. The default value is 1024. The stack (and other data allocations)
are always stored in the local core memory, to avoid conflicts with static data allocations
Expand Down Expand Up @@ -359,6 +373,7 @@ def AIE_CoreOp: AIE_Op<"core", [
int colIndex();
int rowIndex();
bool isMemWest() { return ((rowIndex() % 2) == 0); };
bool isEmpty();
TileOp getTileOp();
using ::xilinx::AIE::TileElement::Trait<CoreOp>::getAsmResultNames;
}];
Expand Down
10 changes: 3 additions & 7 deletions include/aie/Dialect/AIE/Transforms/AIEPasses.h
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ createAIEAssignBufferDescriptorIDsPass();
std::unique_ptr<mlir::OperationPass<DeviceOp>>
createAIEGenerateColumnControlOverlayPass();
std::unique_ptr<mlir::OperationPass<DeviceOp>> createAIEAssignTileCtrlIDsPass();
std::unique_ptr<mlir::OperationPass<DeviceOp>> createAIESetELFforCorePass();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::unique_ptr<mlir::OperationPass<DeviceOp>> createAIESetELFforCorePass();

I think this was removed?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed, thanks for catching this


/// Generate the code for registering passes.
#define GEN_PASS_REGISTRATION
Expand All @@ -63,16 +64,11 @@ std::unique_ptr<mlir::OperationPass<DeviceOp>> createAIEAssignTileCtrlIDsPass();
/// 5. rewrite stream-switches (within a bounding box) back to flows
struct AIEPathfinderPass : AIERoutePathfinderFlowsBase<AIEPathfinderPass> {

DynamicTileAnalysis analyzer;
mlir::DenseMap<TileID, mlir::Operation *> tiles;

AIEPathfinderPass() = default;
AIEPathfinderPass(DynamicTileAnalysis analyzer)
: analyzer(std::move(analyzer)) {}

void runOnOperation() override;
void runOnFlow(DeviceOp d);
void runOnPacketFlow(DeviceOp d, mlir::OpBuilder &builder);
void runOnFlow(DeviceOp d, DynamicTileAnalysis &analyzer);
void runOnPacketFlow(DeviceOp d, mlir::OpBuilder &builder, DynamicTileAnalysis &analyzer);

typedef std::pair<mlir::Operation *, Port> PhysPort;

Expand Down
21 changes: 21 additions & 0 deletions include/aie/Dialect/AIE/Transforms/AIEPasses.td
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def AIECoreToStandard : Pass<"aie-standard-lowering", "mlir::ModuleOp"> {

}];
let options = [
Option<"deviceName", "device", "std::string", /*default=*/"\"\"", "Device to generate code for">,
Option<"tileCol", "tilecol", "unsigned",
/*default=*/"-1", "X coordinate of tile to generate code for">,
Option<"tileRow", "tilerow", "unsigned",
Expand Down Expand Up @@ -272,4 +273,24 @@ def AIEGenerateColumnControlOverlay : Pass<"aie-generate-column-control-overlay"
];
}

def AIESetELFforCore : Pass<"aie-set-elf-for-core", "DeviceOp"> {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could do this one in memory in aiecc main.py:

def set_elf_file_on_tile(module, row, col, path):
    for core in find_ops(
        module.operation,
        lambda o: isinstance(o.operation.opview, CoreOp)
        and o.tile.owner.opview.col.value == col
        and o.tile.owner.opview.row.value == row,
    ):
        core.attributes['elf_file'] = StringAttr.get(path)
    return module

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yes that's much better. I knew as I was doing it that a whole pass for this was overkill but I didn't think of this obvious solution

let summary = "Set the ELF file for a core";
let description = [{
This pass sets the `elf_file` attribute for the given core in the design,
erasing the core's MLIR body.
}];

let constructor = "xilinx::AIE::createAIESetELFforCorePass()";
let dependentDialects = [
"xilinx::AIE::AIEDialect",
];

let options = [
Option<"clDevice", "device", "std::string", /*default=*/"\"\"", "Device for whose cores ELF file should be set.">,
Option<"clTileCol", "col", "unsigned", /*default=*/"0", "Column index of tile to set the ELF file for.">,
Option<"clTileRow", "row", "unsigned", /*default=*/"0", "Row index of tile to set the ELF file for.">,
Option<"clElfFile", "elf-file", "std::string", /*default=*/"", "Path to the ELF file to set for the core.">,
];
}

#endif
3 changes: 3 additions & 0 deletions include/aie/Dialect/AIE/Transforms/AIEPathFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -245,6 +245,9 @@ class DynamicTileAnalysis {

DynamicTileAnalysis() : pathfinder(std::make_shared<Pathfinder>()) {}
DynamicTileAnalysis(std::shared_ptr<Router> p) : pathfinder(std::move(p)) {}
DynamicTileAnalysis(mlir::Operation *op) :
pathfinder(std::make_shared<Pathfinder>()) {
}

mlir::LogicalResult runAnalysis(DeviceOp &device);

Expand Down
22 changes: 22 additions & 0 deletions include/aie/Dialect/AIEX/AIEUtils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===- AIEUtils.h -----------------------------------------------*- C++ -*-===//
//
// This file is licensed under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// (c) Copyright 2025 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

#include "mlir/Dialect/MemRef/IR/MemRef.h"
#include "aie/Dialect/AIE/IR/AIEDialect.h"

using namespace mlir;

namespace xilinx {
namespace AIEX {

memref::GlobalOp getOrCreateDataMemref(OpBuilder &builder, AIE::DeviceOp dev, mlir::Location loc, ArrayRef<uint32_t> words);

}
}
67 changes: 65 additions & 2 deletions include/aie/Dialect/AIEX/IR/AIEX.td
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ include "aie/Dialect/AIE/IR/AIEInterfaces.td"
include "mlir/IR/OpBase.td"
include "mlir/IR/AttrTypeBase.td"
include "mlir/IR/EnumAttr.td"
include "mlir/IR/BuiltinAttributes.td"
include "mlir/IR/SymbolInterfaces.td"
include "mlir/Interfaces/SideEffectInterfaces.td"
include "mlir/Interfaces/DataLayoutInterfaces.td"
Expand Down Expand Up @@ -527,7 +528,11 @@ def AIE_SelectOp: AIEX_Op<"select", []>, Results<(outs Index)> {
];
}

def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator, HasParent<"AIE::DeviceOp">]> {
def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [
Symbol,
NoTerminator,
HasParent<"AIE::DeviceOp">,
]> {
let summary = "Program the configuration co-processor of the AI Engine array";
let description = [{
Instructions in this operation allow for runtime (re-)configuration of the AI Engine array, such as configuring data movement buffer descriptors.
Expand All @@ -537,13 +542,61 @@ def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [NoTerminator, HasParent
The input arguments are arguments passed in from the host at kernel invocation time. This may include buffers on the host.
}];
let arguments = (
ins OptionalAttr<SymbolNameAttr>:$sym_name
ins DefaultValuedAttr<SymbolNameAttr, "xilinx::AIEX::defaultRuntimeSequenceName">:$sym_name
);
let regions = (region
AnyRegion:$body
);
let hasCustomAssemblyFormat = 1;
let hasVerifier = 1;
let extraClassDeclaration = [{
static RuntimeSequenceOp getForSymbolInDevice(AIE::DeviceOp module, llvm::StringRef symbol);
static RuntimeSequenceOp getForSymbolInDeviceOrError(AIE::DeviceOp module, llvm::StringRef symbol);
}];
}

def AIE_ConfigureOp: AIEX_Op<"configure", [
HasParent<"RuntimeSequenceOp">,
NoTerminator
]>,
Results<(outs Index:$result)>
{
let summary = "Set up a configuration (program memories, stream switches, etc.) on the NPU device.";
let arguments = (
ins FlatSymbolRefAttr:$symbol
);

let assemblyFormat = [{
$symbol regions attr-dict
}];

let extraClassDeclaration = [{
AIE::DeviceOp getReferencedDeviceOp();
}];

let regions = (region
AnyRegion:$body
);

let hasVerifier = 1;
}

def AIE_RunOp: AIEX_Op<"run", [HasParent<"ConfigureOp">]> {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please add a short summary for this operation?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done!

let arguments = (
ins FlatSymbolRefAttr:$runtime_sequence_symbol,
Variadic<AnyType>:$args
);

let assemblyFormat = [{
$runtime_sequence_symbol `(` $args `)` `:` `(` type($args) `)` attr-dict
}];

let extraClassDeclaration = [{
AIE::DeviceOp getCalleeDeviceOp();
RuntimeSequenceOp getCalleeRuntimeSequenceOp();
}];

let hasVerifier = 1;
}

def AIE_NpuDmaMemcpyNdOp: AIEX_Op<"npu.dma_memcpy_nd", [
Expand Down Expand Up @@ -772,6 +825,9 @@ def AIE_NpuWrite32Op: AIEX_Op<"npu.write32", []> {
If 'buffer' is not present and 'column' and 'row' are not present then
'address' is interpreted as a full 32-bit address in the AIE array.
}];
let extraClassDeclaration = [{
std::optional<uint32_t> getAbsoluteAddress();
}];
}

// MASKWRITE
Expand All @@ -798,6 +854,9 @@ def AIE_NpuMaskWrite32Op: AIEX_Op<"npu.maskwrite32", []> {
If 'buffer' is not present and 'column' and 'row' are not present then
'address' is interpreted as a full 32-bit address in the AIE array.
}];
let extraClassDeclaration = [{
std::optional<uint32_t> getAbsoluteAddress();
}];
}

// BLOCKWRITE
Expand All @@ -823,6 +882,10 @@ def AIE_NpuBlockWriteOp: AIEX_Op<"npu.blockwrite", []> {
If 'buffer' is not present and 'column' and 'row' are not present then
'address' is interpreted as a full 32-bit address in the AIE array.
}];
let extraClassDeclaration = [{
std::optional<uint32_t> getAbsoluteAddress();
mlir::DenseIntElementsAttr getDataWords();
}];
}

// OP_SYNC
Expand Down
10 changes: 10 additions & 0 deletions include/aie/Dialect/AIEX/IR/AIEXDialect.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,12 @@

#include "aie/Dialect/AIE/IR/AIEDialect.h"

#include "mlir/IR/BuiltinAttributes.h"

namespace xilinx::AIEX {
const char defaultRuntimeSequenceName[] = "sequence";
Copy link
Collaborator

@fifield fifield Sep 25, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be in the op like RuntimeSequenceOp::defaultName and still work in tablegen?
Or better,

let extraClassDeclaration = [{
     llvm::StringRef getDefaultName() { return "sequence"; }
}];

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I can do it but it would have to be a static method, since the getDefaultRuntimeSequenceName() gets called when the builder is instantiated but before the Op gets created.

}

// Include dialect declarations such as parseAttributes, parseType
#include "aie/Dialect/AIEX/IR/AIEXDialect.h.inc"
#include "mlir/IR/Operation.h"
Expand All @@ -24,6 +30,10 @@
#define GET_TYPEDEF_CLASSES
#include "aie/Dialect/AIEX/IR/AIEXTypes.h.inc"

#include "llvm/ADT/StringRef.h"

#include <optional>

namespace xilinx {
namespace AIEX {

Expand Down
Loading
Loading