Skip to content

Commit

Permalink
[AIE2] Fix support for cascade ops
Browse files Browse the repository at this point in the history
Cascade operations operate on wide data types, 512-bits wide in
aie2.  This patch generalizes the dialect support for cascade
to go through backend code generation.
  • Loading branch information
stephenneuendorffer committed Dec 6, 2023
1 parent 01aba90 commit b399452
Show file tree
Hide file tree
Showing 9 changed files with 195 additions and 10 deletions.
12 changes: 8 additions & 4 deletions include/aie/Dialect/AIE/IR/AIEOps.td
Original file line number Diff line number Diff line change
Expand Up @@ -1279,23 +1279,27 @@ def AIE_PutStreamOp: AIE_Op<"putStream", [HasParent<"CoreOp">]> {
}];
}

def AIE_GetCascadeOp: AIE_Op<"getCascade", [HasParent<"CoreOp">]>, Results<(outs AnyI<384>)> {
def AIE_GetCascadeOp: AIE_Op<"getCascade", [HasParent<"CoreOp">]>, Results<(outs AnyType:$cascadeValue)> {
let summary = "An op to read from a cascading stream from a neighboring core";
let description = [{
An op to read from a cascading stream from a neighboring core.
The result type of this operation must have a size that matches the cascade size,
which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32>
}];
let results = (outs AnyI<384>:$cascadeValue);
let hasVerifier = 1;
let assemblyFormat = [{ `(` `)` attr-dict `:` type($cascadeValue) }];
}

def AIE_PutCascadeOp: AIE_Op<"putCascade", [HasParent<"CoreOp">]> {
let summary = "An op to write to a cascading stream from a neighboring core";
let description = [{
An op to write to a cascading stream from a neighboring core.
The argument type of this operation must have a size that matches the cascade size,
which is architecture-dependent. e.g. AIE1: i384 or vector<8xi48> AIE2: i512 or vector<16xi32>
}];

let arguments = (ins AnyI<384>:$cascadeValue);

let arguments = (ins AnyType:$cascadeValue);
let hasVerifier = 1;
let assemblyFormat = [{ `(` $cascadeValue `:` type($cascadeValue) `)` attr-dict }];
}

Expand Down
34 changes: 34 additions & 0 deletions lib/Dialect/AIE/IR/AIEDialect.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -802,6 +802,40 @@ ObjectFifoCreateOp ObjectFifoRegisterProcessOp::getObjectFifo() {
return {};
}

// PutCascadeOp
LogicalResult PutCascadeOp::verify() {
const auto &targetModel = getTargetModel(*this);
Type type = getCascadeValue().getType();
DataLayout dataLayout = DataLayout::closest(*this);
auto bits = dataLayout.getTypeSizeInBits(type);
if(targetModel.getTargetArch() == AIEArch::AIE1) {

Check failure on line 811 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:811:- if(targetModel.getTargetArch() == AIEArch::AIE1) { lib/Dialect/AIE/IR/AIEDialect.cpp:812:- if(bits != 384) lib/Dialect/AIE/IR/AIEDialect.cpp:811:+ if (targetModel.getTargetArch() == AIEArch::AIE1) { lib/Dialect/AIE/IR/AIEDialect.cpp:812:+ if (bits != 384)
if(bits != 384)
return emitOpError("must be a 384-bit type");
} else if(targetModel.getTargetArch() == AIEArch::AIE2) {

Check failure on line 814 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:814:- } else if(targetModel.getTargetArch() == AIEArch::AIE2) { lib/Dialect/AIE/IR/AIEDialect.cpp:815:- if(bits != 512) lib/Dialect/AIE/IR/AIEDialect.cpp:814:+ } else if (targetModel.getTargetArch() == AIEArch::AIE2) { lib/Dialect/AIE/IR/AIEDialect.cpp:815:+ if (bits != 512)
if(bits != 512)
return emitOpError("must be a 512-bit type");
} else
return emitOpError("cascade not supported in ") << stringifyAIEArch(targetModel.getTargetArch());

Check failure on line 818 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:818:- return emitOpError("cascade not supported in ") << stringifyAIEArch(targetModel.getTargetArch()); lib/Dialect/AIE/IR/AIEDialect.cpp:818:+ return emitOpError("cascade not supported in ") lib/Dialect/AIE/IR/AIEDialect.cpp:819:+ << stringifyAIEArch(targetModel.getTargetArch());
return success();
}

// GetCascadeOp
LogicalResult GetCascadeOp::verify() {
const auto &targetModel = getTargetModel(*this);
Type type = getCascadeValue().getType();

Check failure on line 825 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:825:- Type type = getCascadeValue().getType(); lib/Dialect/AIE/IR/AIEDialect.cpp:826:+ Type type = getCascadeValue().getType();
DataLayout dataLayout = DataLayout::closest(*this);
auto bits = dataLayout.getTypeSizeInBits(type);
if(targetModel.getTargetArch() == AIEArch::AIE1) {

Check failure on line 828 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:828:- if(targetModel.getTargetArch() == AIEArch::AIE1) { lib/Dialect/AIE/IR/AIEDialect.cpp:829:- if(bits != 384) lib/Dialect/AIE/IR/AIEDialect.cpp:829:+ if (targetModel.getTargetArch() == AIEArch::AIE1) { lib/Dialect/AIE/IR/AIEDialect.cpp:830:+ if (bits != 384)
if(bits != 384)
return emitOpError("must be a 384-bit type");
} else if(targetModel.getTargetArch() == AIEArch::AIE2) {

Check failure on line 831 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:831:- } else if(targetModel.getTargetArch() == AIEArch::AIE2) { lib/Dialect/AIE/IR/AIEDialect.cpp:832:- if(bits != 512) lib/Dialect/AIE/IR/AIEDialect.cpp:832:+ } else if (targetModel.getTargetArch() == AIEArch::AIE2) { lib/Dialect/AIE/IR/AIEDialect.cpp:833:+ if (bits != 512)
if(bits != 512)
return emitOpError("must be a 512-bit type");
} else
return emitOpError("cascade not supported in ") << stringifyAIEArch(targetModel.getTargetArch());

Check failure on line 835 in lib/Dialect/AIE/IR/AIEDialect.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/IR/AIEDialect.cpp:835:- return emitOpError("cascade not supported in ") << stringifyAIEArch(targetModel.getTargetArch()); lib/Dialect/AIE/IR/AIEDialect.cpp:836:+ return emitOpError("cascade not supported in ") lib/Dialect/AIE/IR/AIEDialect.cpp:837:+ << stringifyAIEArch(targetModel.getTargetArch());
return success();
}

const AIETargetModel &DeviceOp::getTargetModel() {
switch (getDevice()) {
case AIEDevice::xcvc1902:
Expand Down
23 changes: 17 additions & 6 deletions lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ static auto getAIE1Intrinsics(OpBuilder &builder) {

static auto getAIE2Intrinsics(OpBuilder &builder) {
Type int32Type = IntegerType::get(builder.getContext(), 32);
Type int512Type = IntegerType::get(builder.getContext(), 512);
Type accType = VectorType::get({16}, int32Type);
IntrinsicDecls functions = {
{"debug_i32", {int32Type}, {}},
{"llvm.aie2.put.ms", {int32Type, int32Type}, {}}, //(%value, %tlast) -> ()
{"llvm.aie2.get.ss", {}, {int32Type, int32Type}}, //() -> (%value, %tlast)
{"llvm.aie2.put.mcd", {int512Type}, {}},
{"llvm.aie2.get.scd", {}, {int512Type}},
{"llvm.aie2.mcd.write.vec", {accType, int32Type}, {}}, // (%value, %enable) -> ()

Check failure on line 94 in lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp

View workflow job for this annotation

GitHub Actions / Check code format

[clang-format] reported by reviewdog 🐶 Raw Output: lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:94:- {"llvm.aie2.mcd.write.vec", {accType, int32Type}, {}}, // (%value, %enable) -> () lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:95:- {"llvm.aie2.scd.read.vec", {int32Type}, {accType}}, // (%enable) -> (%value) lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:94:+ {"llvm.aie2.mcd.write.vec", lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:95:+ {accType, int32Type}, lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:96:+ {}}, // (%value, %enable) -> () lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:97:+ {"llvm.aie2.scd.read.vec", lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:98:+ {int32Type}, lib/Dialect/AIE/Transforms/AIECoreToStandard.cpp:99:+ {accType}}, // (%enable) -> (%value)
{"llvm.aie2.scd.read.vec", {int32Type}, {accType}}, // (%enable) -> (%value)
{"llvm.aie2.acquire",
{int32Type, int32Type},
{}}, //(%lock_id, %lock_val) -> ()
Expand Down Expand Up @@ -275,13 +275,18 @@ struct AIEPutCascadeToStdLowering : OpConversionPattern<PutCascadeOp> {
if (targetModel.getTargetArch() == AIEArch::AIE1)
funcName = "llvm.aie.put.mcd";
else
funcName = "llvm.aie2.put.mcd";
funcName = "llvm.aie2.mcd.write.vec";
auto putMCDFunc = module.lookupSymbol<func::FuncOp>(funcName);
if (!putMCDFunc)
return op.emitOpError("Could not find the intrinsic function ")
<< funcName;
SmallVector<Value, 2> args;
args.push_back(op.getCascadeValue());
if (targetModel.getTargetArch() == AIEArch::AIE2)
args.push_back(rewriter.create<arith::ConstantOp>(
op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
rewriter.getI32IntegerAttr(1))); // enable

rewriter.create<func::CallOp>(rewriter.getUnknownLoc(), putMCDFunc, args);
rewriter.eraseOp(Op);
return success();
Expand All @@ -305,13 +310,19 @@ struct AIEGetCascadeToStdLowering : OpConversionPattern<GetCascadeOp> {
if (targetModel.getTargetArch() == AIEArch::AIE1)
funcName = "llvm.aie.get.scd";
else
funcName = "llvm.aie2.get.scd";
funcName = "llvm.aie2.scd.read.vec";
auto getSCDFunc = module.lookupSymbol<func::FuncOp>(funcName);
if (!getSCDFunc)
return op.emitOpError("Could not find the intrinsic function ")
<< funcName;
SmallVector<Value, 2> args;
if (targetModel.getTargetArch() == AIEArch::AIE2)
args.push_back(rewriter.create<arith::ConstantOp>(
op.getLoc(), IntegerType::get(rewriter.getContext(), 32),
rewriter.getI32IntegerAttr(1))); // enable

auto getSCDCall = rewriter.create<func::CallOp>(rewriter.getUnknownLoc(),
getSCDFunc, ValueRange({}));
getSCDFunc, args);
rewriter.replaceOp(op, getSCDCall.getResult(0));
return success();
}
Expand Down
23 changes: 23 additions & 0 deletions test/dialect/AIE/badcascade-vc1902.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===- badcore.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 2023 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

// RUN: not aie-opt %s 2>&1 | FileCheck %s
// CHECK: error{{.*}}'AIE.putCascade' op must be a 384-bit type

module @test {
AIE.device(xcvc1902) {
%t33 = AIE.tile(3, 3)
%c33 = AIE.core(%t33) {
%val2 = arith.constant 1 : i64
AIE.putCascade(%val2: i64)
AIE.end
}
}
}
23 changes: 23 additions & 0 deletions test/dialect/AIE/badcascade-ve2802.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===- badcore.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 2023 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

// RUN: not aie-opt %s 2>&1 | FileCheck %s
// CHECK: error{{.*}}'AIE.putCascade' op must be a 512-bit type

module @test {
AIE.device(xcve2802) {
%t33 = AIE.tile(3, 3)
%c33 = AIE.core(%t33) {
%val2 = arith.constant 1 : i64
AIE.putCascade(%val2: i64)
AIE.end
}
}
}
22 changes: 22 additions & 0 deletions test/dialect/AIE/badgetcascade-vc1902.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===- badcore.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 2023 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

// RUN: not aie-opt %s 2>&1 | FileCheck %s
// CHECK: error{{.*}}'AIE.getCascade' op must be a 384-bit type

module @test {
AIE.device(xcvc1902) {
%t33 = AIE.tile(3, 3)
%c33 = AIE.core(%t33) {
%val2 = AIE.getCascade() : i64
AIE.end
}
}
}
22 changes: 22 additions & 0 deletions test/dialect/AIE/badgetcascade-ve2802.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//===- badcore.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 2023 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

// RUN: not aie-opt %s 2>&1 | FileCheck %s
// CHECK: error{{.*}}'AIE.getCascade' op must be a 512-bit type

module @test {
AIE.device(xcve2802) {
%t33 = AIE.tile(3, 3)
%c33 = AIE.core(%t33) {
%val2 = AIE.getCascade() : i64
AIE.end
}
}
}
23 changes: 23 additions & 0 deletions test/dialect/AIE/cascade-vc1902.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// NOTE: Assertions have been autogenerated by utils/update_mlir_test_checks.py
//===- cascade-ve2802.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 2023 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

// RUN: aie-opt %s

module @test {
AIE.device(xcvc1902) {
%t33 = AIE.tile(3, 3)
%c33 = AIE.core(%t33) {
%val2 = AIE.getCascade() : i384
AIE.putCascade(%val2: i384)
AIE.end
}
}
}
23 changes: 23 additions & 0 deletions test/dialect/AIE/cascade-ve2802.mlir
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
//===- cascade-ve2802.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 2023 Advanced Micro Devices, Inc.
//
//===----------------------------------------------------------------------===//

// RUN: aie-opt %s

module @test {
AIE.device(xcve2802) {
%t33 = AIE.tile(3, 3)
%c33 = AIE.core(%t33) {
%val2 = AIE.getCascade() : vector<16xi32>
AIE.putCascade(%val2: vector<16xi32>)
AIE.end

}
}
}

0 comments on commit b399452

Please sign in to comment.