Skip to content

Commit a7df6e1

Browse files
authored
Promote runtime_sequence to aie dialect (#2708)
1 parent abf56b9 commit a7df6e1

153 files changed

Lines changed: 376 additions & 375 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

include/aie/Dialect/AIE/IR/AIEOps.td

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2106,4 +2106,34 @@ def AIE_BDChainOp: AIE_Op<"bd_chain", [Symbol, SkipAccessibilityCheckTrait]> {
21062106

21072107
}
21082108

2109+
def AIE_RuntimeSequenceOp : AIE_Op<"runtime_sequence", [
2110+
Symbol,
2111+
NoTerminator,
2112+
HasParent<"DeviceOp">,
2113+
]> {
2114+
let summary = "Program the configuration co-processor of the AI Engine array";
2115+
let description = [{
2116+
Instructions in this operation allow for runtime (re-)configuration of the AI Engine array, such as configuring data movement buffer descriptors.
2117+
These instructions will execute on the configuration co-processor of the AI Engine array.
2118+
2119+
Typically, these instructions include configuring the data transfers between host and AIE array on the shims.
2120+
The input arguments are arguments passed in from the host at kernel invocation time. This may include buffers on the host.
2121+
}];
2122+
let arguments = (
2123+
ins DefaultValuedAttr<SymbolNameAttr, "getDefaultRuntimeSequenceName()">:$sym_name
2124+
);
2125+
let regions = (region
2126+
AnyRegion:$body
2127+
);
2128+
let hasCustomAssemblyFormat = 1;
2129+
let hasVerifier = 1;
2130+
let extraClassDeclaration = [{
2131+
static llvm::StringRef getDefaultRuntimeSequenceName() { return "sequence"; }
2132+
static RuntimeSequenceOp getForSymbolInDevice(DeviceOp module, llvm::StringRef symbol);
2133+
static RuntimeSequenceOp getForSymbolInDeviceOrError(DeviceOp module, llvm::StringRef symbol);
2134+
}];
2135+
let extraClassDefinition = [{
2136+
}];
2137+
}
2138+
21092139
#endif // AIE_OPS

include/aie/Dialect/AIEX/IR/AIEX.td

Lines changed: 12 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -528,38 +528,11 @@ def AIE_SelectOp: AIEX_Op<"select", []>, Results<(outs Index)> {
528528
];
529529
}
530530

531-
def AIE_RuntimeSequenceOp : AIEX_Op<"runtime_sequence", [
532-
Symbol,
533-
NoTerminator,
534-
HasParent<"AIE::DeviceOp">,
535-
]> {
536-
let summary = "Program the configuration co-processor of the AI Engine array";
537-
let description = [{
538-
Instructions in this operation allow for runtime (re-)configuration of the AI Engine array, such as configuring data movement buffer descriptors.
539-
These instructions will execute on the configuration co-processor of the AI Engine array.
540-
541-
Typically, these instructions include configuring the data transfers between host and AIE array on the shims.
542-
The input arguments are arguments passed in from the host at kernel invocation time. This may include buffers on the host.
543-
}];
544-
let arguments = (
545-
ins DefaultValuedAttr<SymbolNameAttr, "getDefaultRuntimeSequenceName()">:$sym_name
546-
);
547-
let regions = (region
548-
AnyRegion:$body
549-
);
550-
let hasCustomAssemblyFormat = 1;
551-
let hasVerifier = 1;
552-
let extraClassDeclaration = [{
553-
static llvm::StringRef getDefaultRuntimeSequenceName() { return "sequence"; }
554-
static RuntimeSequenceOp getForSymbolInDevice(AIE::DeviceOp module, llvm::StringRef symbol);
555-
static RuntimeSequenceOp getForSymbolInDeviceOrError(AIE::DeviceOp module, llvm::StringRef symbol);
556-
}];
557-
let extraClassDefinition = [{
558-
}];
559-
}
531+
// NOTE: runtime_sequence operation has been moved to the AIE dialect (AIEOps.td)
532+
// Use aie.runtime_sequence instead of aiex.runtime_sequence
560533

561534
def AIE_ConfigureOp: AIEX_Op<"configure", [
562-
HasParent<"RuntimeSequenceOp">,
535+
HasParent<"AIE::RuntimeSequenceOp">,
563536
NoTerminator
564537
]>,
565538
Results<(outs Index:$result)>
@@ -596,7 +569,7 @@ def AIE_RunOp: AIEX_Op<"run", [HasParent<"ConfigureOp">]> {
596569

597570
let extraClassDeclaration = [{
598571
AIE::DeviceOp getCalleeDeviceOp();
599-
RuntimeSequenceOp getCalleeRuntimeSequenceOp();
572+
AIE::RuntimeSequenceOp getCalleeRuntimeSequenceOp();
600573
}];
601574

602575
let hasVerifier = 1;
@@ -1044,7 +1017,7 @@ def AIE_NpuLoadPdiOp: AIEX_Op<"npu.load_pdi", []> {
10441017
}];
10451018
}
10461019

1047-
def AIE_DMAConfigureTaskOp : AIEX_Op<"dma_configure_task", [HasParent<"RuntimeSequenceOp">, TileElement]>, Results<(outs Index:$result)> {
1020+
def AIE_DMAConfigureTaskOp : AIEX_Op<"dma_configure_task", [HasParent<"AIE::RuntimeSequenceOp">, TileElement]>, Results<(outs Index:$result)> {
10481021
let summary = "Concrete Instantiation of a Buffer Descriptor Chain as a Task on a Channel and Direction on a Tile";
10491022
let description = [{
10501023
Encapsulates the DMA configuration of one task, that is the (chain of) buffer descriptors to be executed on a given channel and direction on a tile.
@@ -1095,7 +1068,7 @@ def AIE_DMAConfigureTaskOp : AIEX_Op<"dma_configure_task", [HasParent<"RuntimeSe
10951068
];
10961069
}
10971070

1098-
def AIE_DMAConfigureTaskForOp : AIEX_Op<"dma_configure_task_for", [HasParent<"RuntimeSequenceOp">]>, Results<(outs Index:$result)> {
1071+
def AIE_DMAConfigureTaskForOp : AIEX_Op<"dma_configure_task_for", [HasParent<"AIE::RuntimeSequenceOp">]>, Results<(outs Index:$result)> {
10991072
let summary = "As dma_configure_task, but specify tile, direction and channel by reference to a Shim DMA allocation op";
11001073

11011074
let arguments = (
@@ -1109,7 +1082,7 @@ def AIE_DMAConfigureTaskForOp : AIEX_Op<"dma_configure_task_for", [HasParent<"Ru
11091082
let assemblyFormat = [{ $alloc regions attr-dict }];
11101083
}
11111084

1112-
def AIE_DMAFreeTaskOp : AIEX_Op<"dma_free_task", [HasParent<"RuntimeSequenceOp">]> {
1085+
def AIE_DMAFreeTaskOp : AIEX_Op<"dma_free_task", [HasParent<"AIE::RuntimeSequenceOp">]> {
11131086
let summary = "Free all Buffer Descriptor IDs Associated with the Given Task";
11141087
let description = [{
11151088
This operation informs the static buffer descriptor allocator pass in the compiler that the buffer descriptor IDs it has allocated to the BDs inside the referenced task can be reused thereafter.
@@ -1133,7 +1106,7 @@ def AIE_DMAFreeTaskOp : AIEX_Op<"dma_free_task", [HasParent<"RuntimeSequenceOp">
11331106
}];
11341107
}
11351108

1136-
def AIE_DMAStartTaskOp : AIEX_Op<"dma_start_task", [HasParent<"RuntimeSequenceOp">]> {
1109+
def AIE_DMAStartTaskOp : AIEX_Op<"dma_start_task", [HasParent<"AIE::RuntimeSequenceOp">]> {
11371110
let summary = "Submit a Preconfigured Task to the Task Queue";
11381111
let description = [{
11391112
Submits the referenced task for execution on the tile, channel and direction it has been configured to run on.
@@ -1157,7 +1130,7 @@ def AIE_DMAStartTaskOp : AIEX_Op<"dma_start_task", [HasParent<"RuntimeSequenceOp
11571130
}];
11581131
}
11591132

1160-
def AIE_DMAAwaitTaskOp : AIEX_Op<"dma_await_task", [HasParent<"RuntimeSequenceOp">]> {
1133+
def AIE_DMAAwaitTaskOp : AIEX_Op<"dma_await_task", [HasParent<"AIE::RuntimeSequenceOp">]> {
11611134
let summary = "Await Completion of a Previously Submitted DMA Task";
11621135
let description = [{
11631136
This operation will block execution of the runtime sequence until the referenced previously started DMA task has completed.
@@ -1184,7 +1157,7 @@ def AIE_DMAAwaitTaskOp : AIEX_Op<"dma_await_task", [HasParent<"RuntimeSequenceOp
11841157
}];
11851158
}
11861159

1187-
def AIE_DMAStartBdChainOp: AIEX_Op<"dma_start_bd_chain", [HasParent<"RuntimeSequenceOp">, TileElement]>,
1160+
def AIE_DMAStartBdChainOp: AIEX_Op<"dma_start_bd_chain", [HasParent<"AIE::RuntimeSequenceOp">, TileElement]>,
11881161
Results<(outs Index:$result)>
11891162
{
11901163

@@ -1223,7 +1196,7 @@ def AIE_DMAStartBdChainOp: AIEX_Op<"dma_start_bd_chain", [HasParent<"RuntimeSequ
12231196

12241197
}
12251198

1226-
def AIE_DMAStartBdChainForOp: AIEX_Op<"dma_start_bd_chain_for", [HasParent<"RuntimeSequenceOp">]>,
1199+
def AIE_DMAStartBdChainForOp: AIEX_Op<"dma_start_bd_chain_for", [HasParent<"AIE::RuntimeSequenceOp">]>,
12271200
Results<(outs Index:$result)>
12281201
{
12291202
let summary = "As dma_start_bd_chain, but specify tile, direction and channel by reference to a Shim DMA allocation op";
@@ -1241,7 +1214,7 @@ def AIE_DMAStartBdChainForOp: AIEX_Op<"dma_start_bd_chain_for", [HasParent<"Runt
12411214
}];
12421215
}
12431216

1244-
def AIEX_SetLockOp: AIEX_Op<"set_lock", [HasParent<"RuntimeSequenceOp">, SkipAccessibilityCheckTrait]> {
1217+
def AIEX_SetLockOp: AIEX_Op<"set_lock", [HasParent<"AIE::RuntimeSequenceOp">, SkipAccessibilityCheckTrait]> {
12451218
let summary = "Set the value of a lock";
12461219
let description = [{
12471220
This operation sets the value of `lock` inside of a RuntimeSequenceOp.

lib/Conversion/AIEToConfiguration/AIEToConfiguration.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -675,7 +675,7 @@ static LogicalResult convertTransactionOpsToMLIR(
675675
while (device.lookupSymbol(seq_name))
676676
seq_name = "configure" + std::to_string(id++);
677677
StringAttr seq_sym_name = builder.getStringAttr(seq_name);
678-
auto seq = builder.create<AIEX::RuntimeSequenceOp>(loc, seq_sym_name);
678+
auto seq = builder.create<AIE::RuntimeSequenceOp>(loc, seq_sym_name);
679679
seq.getBody().push_back(new Block);
680680

681681
builder.setInsertionPointToStart(&seq.getBody().front());

lib/Dialect/AIE/IR/AIEDialect.cpp

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2333,6 +2333,111 @@ ShimDMAAllocationOp ShimDMAAllocationOp::getForSymbol(DeviceOp device,
23332333
return nullptr;
23342334
}
23352335

2336+
//===----------------------------------------------------------------------===//
2337+
// RuntimeSequenceOp
2338+
//===----------------------------------------------------------------------===//
2339+
2340+
ParseResult RuntimeSequenceOp::parse(OpAsmParser &parser,
2341+
OperationState &result) {
2342+
2343+
// Name of this runtime sequence
2344+
StringAttr nameAttr;
2345+
(void)parser.parseOptionalSymbolName(
2346+
nameAttr, mlir::SymbolTable::getSymbolAttrName(), result.attributes);
2347+
2348+
SmallVector<OpAsmParser::Argument> entryArgs;
2349+
2350+
// Entry arguments, e.g. (%addr: memref<1xi32>)
2351+
ParseResult argParseResult = parser.parseCommaSeparatedList(
2352+
OpAsmParser::Delimiter::Paren, [&]() -> ParseResult {
2353+
OpAsmParser::Argument argument;
2354+
if (parser.parseArgument(argument, true, true)) {
2355+
return failure();
2356+
}
2357+
entryArgs.push_back(argument);
2358+
return success();
2359+
});
2360+
if (argParseResult) {
2361+
return argParseResult;
2362+
}
2363+
2364+
// Body
2365+
auto *body = result.addRegion();
2366+
ParseResult bodyParseResult = parser.parseRegion(*body, entryArgs, false);
2367+
if (bodyParseResult) {
2368+
return bodyParseResult;
2369+
}
2370+
2371+
return success();
2372+
}
2373+
2374+
void RuntimeSequenceOp::print(OpAsmPrinter &printer) {
2375+
Region &body = getRegion();
2376+
2377+
auto nameAttr = (*this)->getAttrOfType<StringAttr>(
2378+
mlir::SymbolTable::getSymbolAttrName());
2379+
if (nameAttr &&
2380+
nameAttr != ::mlir::OpBuilder((*this)->getContext())
2381+
.getStringAttr(getDefaultRuntimeSequenceName())) {
2382+
printer << ' ';
2383+
printer.printSymbolName(nameAttr);
2384+
}
2385+
2386+
printer << '(';
2387+
for (unsigned i = 0, n = body.getNumArguments(); i < n; i++) {
2388+
if (i > 0) {
2389+
printer << ", ";
2390+
}
2391+
printer.printRegionArgument(body.getArgument(i));
2392+
}
2393+
printer << ')';
2394+
2395+
printer << ' ';
2396+
printer.printRegion(body, false, true);
2397+
}
2398+
2399+
LogicalResult RuntimeSequenceOp::verify() {
2400+
DeviceOp device = (*this)->getParentOfType<DeviceOp>();
2401+
if (!device) {
2402+
// this check is redudnant with the HasParent trait, but can't hurt
2403+
(*this)->emitOpError() << "must be inside AIE device operation.";
2404+
return failure();
2405+
}
2406+
return success();
2407+
}
2408+
2409+
RuntimeSequenceOp
2410+
RuntimeSequenceOp::getForSymbolInDevice(DeviceOp deviceOp,
2411+
llvm::StringRef symbol) {
2412+
RuntimeSequenceOp runtimeSequenceOp;
2413+
if (!symbol.size()) {
2414+
runtimeSequenceOp = *deviceOp.getOps<RuntimeSequenceOp>().begin();
2415+
} else {
2416+
Operation *maybeRuntimeSequenceOp =
2417+
mlir::SymbolTable::lookupSymbolIn(deviceOp, symbol);
2418+
if (!maybeRuntimeSequenceOp) {
2419+
return nullptr;
2420+
}
2421+
runtimeSequenceOp =
2422+
llvm::dyn_cast<RuntimeSequenceOp>(maybeRuntimeSequenceOp);
2423+
}
2424+
return runtimeSequenceOp;
2425+
}
2426+
2427+
RuntimeSequenceOp
2428+
RuntimeSequenceOp::getForSymbolInDeviceOrError(DeviceOp deviceOp,
2429+
llvm::StringRef symbol) {
2430+
RuntimeSequenceOp runtimeSequenceOp = getForSymbolInDevice(deviceOp, symbol);
2431+
if (!runtimeSequenceOp) {
2432+
if (!symbol.empty()) {
2433+
deviceOp.emitError("No such runtime sequence: ") << symbol;
2434+
} else {
2435+
deviceOp.emitError("No runtime sequence in device");
2436+
}
2437+
}
2438+
return runtimeSequenceOp;
2439+
}
2440+
23362441
// Include implementations for custom attributes
23372442
#define GET_ATTRDEF_CLASSES
23382443
#include "aie/Dialect/AIE/IR/AIEAttrs.cpp.inc"

0 commit comments

Comments
 (0)