Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[midend/lib/Conversion/LowerLinalgToGemmini] Add pass support for gemmini to run E2E LeNet and some tests. #463

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

shirohasuki
Copy link

[midend/lib/Conversion/LowerLinalgToGemmini] Add conv2d_nhwc_fhwc pass for gemmini and add relevant examples and tests.
[midend/lib/Conversion/LowerGemmini] Add scalar print Op for convenient testing and add relevant examples and tests.
[midend/lib/Dialect/Gemmini] Split gemmini conv's RISC and CISC instruction lowering into two separate passes. (Now it's default lowering to RISC type different from native-gemmini, maybe we need a option to config this. Both can pass the LENet test.)

Below are the RISC version and CISC version running LeNet E2E on firesim.
L%M6F8O34OTEQ39G8FM)5

@shirohasuki
Copy link
Author

The commits seem to be missing the endline? Although I can see them locally.....

%output = memref.alloc() : memref<1x3x3x1xi8>

// CHECK: gemmini.tile_conv %{{[0-9]+}} %alloc_{{[0-9]+}} %alloc_{{[0-9]+}} %alloc_{{[0-9]+}} %{{.+}} %{{.+}} :
// CHECK-SAME: memref<1x7x7x1xi8> memref<25x1xi8> memref<1xi32> memref<9x1xi8> i64 i64
Copy link
Member

Choose a reason for hiding this comment

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

Maybe you don't need check-same, and feel that the content of check-smae is not important. The same is true for the following example.

Copy link
Member

@linuxlonelyeagle linuxlonelyeagle Feb 19, 2025

Choose a reason for hiding this comment

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

gemmini.tile_conv ({{.*}} ({{.*}} ..., Maybe better since you're not capturing the variable and then using it.


ModuleOp parentModule = op->getParentOfType<ModuleOp>();

auto printfRef = getOrInsertPrintf(rewriter, parentModule);
Copy link
Member

Choose a reason for hiding this comment

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

Do not use auto,The data types here can be confusing for people who are not familiar with this code.

valueToPrint = rewriter.create<LLVM::SExtOp>(loc, rewriter.getI32Type(),
valueToPrint);
}

Copy link
Member

Choose a reason for hiding this comment

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

For unsupported data types, you should return failure.

Copy link
Member

@linuxlonelyeagle linuxlonelyeagle left a comment

Choose a reason for hiding this comment

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

Thanks for the work, I just did a quick review.

// CHECK: gemmini.print_scalar %{{.*}} : i8
gemmini.print_scalar %scalar : i8

%vector = memref.alloc() : memref<4xi8> // 1D向量
Copy link
Member

Choose a reason for hiding this comment

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

use English.

@@ -222,6 +311,7 @@ void LowerGemminiToLLVMPass::runOnOperation() {
cf::populateControlFlowToLLVMConversionPatterns(converter, patterns);
populateFuncToLLVMConversionPatterns(converter, patterns);
patterns.add<PrintOpLowering>(&getContext());
patterns.add<PrintScalarOpLowering>(&getContext());
Copy link
Member

Choose a reason for hiding this comment

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

... context = &getContext();
patterns.add<...>(context);

if (stridesAttr)
strides = (*stridesAttr.begin()).getLimitedValue();

if (inputShape[1] != inputShape[2]) // h, w
Copy link
Member

Choose a reason for hiding this comment

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

The comment should be more explicit and should be placed above the if statement.

@linuxlonelyeagle
Copy link
Member

Ping @shirohasuki I don't seem to have approval authority. If no one approves this PR (CI cannot run, please @zhanghb97 in time.

@shirohasuki
Copy link
Author

Thank you so much for the REVIEW! I'll modify it and @zhanghb97 for CI.

@linuxlonelyeagle
Copy link
Member

Print Ops in Gemmini has always been coupled.Its logic should actually be memref -> affine -> scf -> llvm,In fact, Gemmini is just gemmini -> llvm,So maybe you can separate the printOp patterns into a new pass.You can see that the populate pattern functions from the upstream are introduced in the lower gemmini process.

@shirohasuki
Copy link
Author

I think it's right, Separate the printOp pattern into a decoupled pass and it will be like this?

populateGemminiPrintLegalizeForLLVMExportPatterns()
populateGemminiLegalizeForLLVMExportPatterns()
then, affine -> scf -> llvm................

@linuxlonelyeagle
Copy link
Member

I think it's right, Separate the printOp pattern into a decoupled pass and it will be like this?

populateGemminiPrintLegalizeForLLVMExportPatterns()
populateGemminiLegalizeForLLVMExportPatterns()
then, affine -> scf -> llvm................

populateGemminiLegalizeForLLVMExportPatterns() should only include patterns that are lower to the gemmini instructions. And populateGemminiPrintLegalizeForLLVMExportPatterns() should only include patterns for print ops, which lower print ops to MLIR upstream ops.and then use the upstream pass, which should be lower to llvm dialect.

gemmini.print => affine/scf
// then use spsteam pass
affine/scf => llvm dialect

@shirohasuki
Copy link
Author

I think it's right, Separate the printOp pattern into a decoupled pass and it will be like this?

populateGemminiPrintLegalizeForLLVMExportPatterns()
populateGemminiLegalizeForLLVMExportPatterns()
then, affine -> scf -> llvm................

populateGemminiLegalizeForLLVMExportPatterns() should only include patterns that are lower to the gemmini instructions. And populateGemminiPrintLegalizeForLLVMExportPatterns() should only include patterns for print ops, which lower print ops to MLIR upstream ops.and then use the upstream pass, which should be lower to llvm dialect.

gemmini.print => affine/scf
// then use spsteam pass
affine/scf => llvm dialect

I got it!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants