Is this doable using the OneToNOpConversionPattern interface? I tried for some time without any success. When I define the type converter to convert tile<32x16xf16> -> 2 * tile<16x16xf16>, materialization hooks end up inserting unrealized_cast ops for the ops that I need unchanged.
I also tried using usual OpRewritePattern and somehow maintaining the type legality by using manual unrealized_cast insertion which works fine. But it would be much nicer if I can do this using OneToNConversion.
It looks like you need a context-specific type converter: A type converter that is only applied to some ops. Neither the 1:N nor the regular dialect conversion support that at the moment.
You could try to run the 1:N dialect conversion without a type converter (pass a nullptr type converter to the pattern constructor). That should work with the regular dialect conversion and hopefully also the 1:N dialect conversion that you need in your case.
fyi, I am in the process of merging the two dialect conversion drivers, so this part of the API is going to change slightly soon.
I tried this approach, but it did not work out. Then OneToNConversion complains that in some cases there is no 1:N conversions and you have just 1:1 conversion (match in number of outputs). Looks like OneToNConversion is not designed to handle this case.
my conversion pattern does not get called. Also I would like to keep the materialization hooks, because that makes handling control-flow ops much easier with signature conversions.
P.S.
I managed to get whole thing working by just using the 1:1 OpConversionPatterns, few drawbacks there are,
Need to rely on unrealized_cast to reconcile types.
Bit of a pain to handle ops that require signature conversions.
I had to define a conversion target also where I marked the subset of ops that needs to be decomposed as illegal. Can not reply on OpRewritePatterns because I needed a type converter to do the signature conversion on For Ops.
I believe to handle this in 1:N conversion, I need a custom 1:N type converter that allows to look at some of the properties of the op before converting some type. Is there any plan on supporting something like that?
You are manually calling OneToNPatternRewriter::replaceOp, right? Thatâs where the assertion is failing. It looks like you are passing an incorrect resultMapping.
Actually, I donât see how this is related to the type converter. (Or running a conversion pattern without a type converter.) OneToNPatternRewriter::replaceOp does not require a type converter.
Hi @matthias-springer, sorry about the late reply to this thread. With recent changes in the dialect conversion drivers, is this use case supported? To recap I want to 1:N convert a subset of ops in specific op type (say load â 2 loads based on some property of the load).
I was able to do this using some hacks described above, but with recent changes in upstream this no longer works. It crashes with,
LLVM ERROR: pattern 'optimizetranspose::LoadNdOpPattern' does not support 1:N conversion
I can confirm this is doable using both a combination of close study of the framework and 1 or 2 âquestionableâ things; you can take a look at this PR
that I recently put together (with a great deal of help from Matthias) that does exactly what youâre trying to do. Itâs a fairly complex implementation so feel free to reach out if you have trouble seeing the âforest for the treesâ.
Iâm not sure if it will work for your use case, but you can play with ConversionTarget: marking an op as illegal only if a conversion pattern should be applied. If an op is already legal, it will not be touched by the conversion driver.
I am already using a conversion target. Here is my approach in summary,
I define a conversion target that filter outs the subset of ops that I need to 1:N convert using addDynamicallyLegalOp
For the ops that need 1:N conversion, I reply on UnrealizedConversionCast Op to preserve the types. Then I move on to consumers and fix them during conversion.
Code here:
Tricky bit is ForOp handling. Originally I define a OneToNTypeMapping and do a signature conversion to resolve the block argument inside the ForOp. This approach is failing with recent upstream changes. For example, the block arguments are expanded after the 1:N conversion but argument materialization hook does not insert the UnrealizedConversionCast ops I need. Do you have some idea why this is happening?
Argument materializations are deprecated. The conversion driver does not use them anymore. The callback registration function on the type converter is still there, but it will be deleted soon.
Generally speaking, any mechanism that is based on the presence of UnrealizedConversionCastOp is fragile because those are just an implementation detail of the conversion driver.