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

[mlir][test] Test conversion of TOSA to EmitC via LinAlg #94640

Draft
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

ilovepi
Copy link
Contributor

@ilovepi ilovepi commented Jun 6, 2024

This is an important use case for MLGO, to simplify maintenance and
foster easier to share models via C headers.

Created using spr 1.3.4
@ilovepi
Copy link
Contributor Author

ilovepi commented Jun 6, 2024

@mtrofin @simon-camp, sorry that this is about a week behind schedule. I had most of this done last week, but I was trying to figure out why some of the transforms weren't working as expected. I believe that using the tosa-to-linalg.mlir test as a basis may have been a mistake.

Once we settle on the precise input MLIR, alls that's left to do is to validate the generated header via CHECK lines.

@simon-camp perhaps you have an idea why the second RUN line is failing? These are all basically translations from your script, and there shouldn't be any material deviations from the original.

# .---command stderr------------
# | /usr/local/google/home/paulkirth/llvm-fork/build/tools/mlir/test/Conversion/TosaToEmitC/Output/tosa-to-linalg.mlir.tmp.model.linalg.mlir:19:1: error: redefinition of attribute alias id 'map'
# | #map = affine_map<(d0) -> (d0)>
# | ^
# `-----------------------------
# error: command failed with exit status: 1

@simon-camp
Copy link
Contributor

What's happening is that the --split-input-file argument splices the file on the // ----- lines, runs the passes on each chunk independently and joins the results back together. So multiple chunks generate this attribute independently with the same name. This then fails to parse in the next run line.

TL;DR: remove the --split-input-filearguments.

Interestingly the test then runs to line 15 where it crashes. The input to that invocation is this. I expected the lowering to fail there as we support neither dynamic shapes nor 0d memrefs in the conversion to EmitC, but the passes should fail with an error message instead of an assertion. I can take a look at this next week.

@ilovepi
Copy link
Contributor Author

ilovepi commented Jun 7, 2024

What's happening is that the --split-input-file argument splices the file on the // ----- lines, runs the passes on each chunk independently and joins the results back together. So multiple chunks generate this attribute independently with the same name. This then fails to parse in the next run line.

TL;DR: remove the --split-input-filearguments.

Thanks. I'll update the patch in a bit.

Interestingly the test then runs to line 15 where it crashes. The input to that invocation is this. I expected the lowering to fail there as we support neither dynamic shapes nor 0d memrefs in the conversion to EmitC, but the passes should fail with an error message instead of an assertion. I can take a look at this next week.

I guess that may require some of the post processing you mentioned? I'll see if I can add some of those python clean ups you provided in the meantime. We can add some TODO's and remove those as the functionality improves.

@simon-camp
Copy link
Contributor

I pushed a fix for the crash in #94936. I would suggest that you test the script on an actual model, as it should have fixed shapes. That will not run into most of unsupported features seen in the current tests. Feel free to share the input model in the TOSA dialect if things don't work directly.

@ilovepi
Copy link
Contributor Author

ilovepi commented Jun 10, 2024

I pushed a fix for the crash in #94936. I would suggest that you test the script on an actual model, as it should have fixed shapes. That will not run into most of unsupported features seen in the current tests. Feel free to share the input model in the TOSA dialect if things don't work directly.

Thanks for the suggestion. Since this was testing the conversion, from ToSa -> LinAlg -> EmitC, I assumed using the tests for ToSa -> LinAlg would be a good starting point.

I'm not all that familiar w/ how the models are derived. Do you have a suggestion as to how we should generate a minimal case? On the LLVM side, I'd either start w/ some minimal C code and generate IR or write it by hand. I'm a little out of my depth on the MLIR side of things, and its never been clear to me how the MLIR used for MLGO is derived in the first place.

Copy link

github-actions bot commented Oct 3, 2024

✅ With the latest revision this PR passed the Python code formatter.

@ilovepi
Copy link
Contributor Author

ilovepi commented Oct 3, 2024

@simon-camp I finally made some progress here after getting some help from @mtrofin on the saved model. For now I've gone w/ a super simple model from TF Lite and we can use more complex ones once we fix the issues w/ the test/conversion pipeline.

Right now the main blocker I have is that the final --convert-memref-to-emitc is failing to when trying to convert the function argument. Looking at the failure and some of the tests around memref conversion, this seems intentional, as I found tests that are specifically checking that this conversion fails. I would have supposed that this could be transformed into an emitc array type or pointer, but it seems not to be supported.

I think this is happening because we don't have a materialization callback available in TypeConverter::convertSignatureArgs(), but it is not clear to me if we should add something there, add some other transform in the placeholder python script, or take a completely different approach.

Error:

<stdin>:26:5: error: failed to legalize unresolved materialization from ('memref<1xf32>') to '!emitc.array<1xf32>' that remained live after conversion
    memref.store %20, %arg2[%2] : memref<1xf32>
    ^
<stdin>:26:5: note: see current operation: %0 = "builtin.unrealized_conversion_cast"(%arg2) : (memref<1xf32>) -> !emitc.array<1xf32>
<stdin>:26:5: note: see existing live user here: %29 = emitc.subscript %0[%5] : (!emitc.array<1xf32>, index) -> !emitc.lvalue<f32>

Created using spr 1.3.4
@simon-camp
Copy link
Contributor

Hi @ilovepi, @mtrofin. I had some time to look into the failure. I have an idea how to fix the error; I'm just waiting on feedback from other folks before sending a PR. Alongside that I stripped down the pass pipeline to a minimal version working for the new test case.

I have a working prototype here that get's completely rid of the Python hack.

@ilovepi
Copy link
Contributor Author

ilovepi commented Oct 15, 2024

@simon-camp, that's great news! The prototype looks much nicer than using the complicated nest of RUN lines. Is there a PR for the prototype yet? if so, we can probably abandon this, since your implementation looks much better, and we can just keep incrementally adding more test cases after that.

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