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] Bug in MemrefToLLVM lowering pattern for memref.transpose #65145

Closed
ubfx opened this issue Aug 31, 2023 · 3 comments
Closed

[mlir] Bug in MemrefToLLVM lowering pattern for memref.transpose #65145

ubfx opened this issue Aug 31, 2023 · 3 comments
Assignees

Comments

@ubfx
Copy link
Member

ubfx commented Aug 31, 2023

Permutation maps can sometimes be confusing because it's easy to mix up the source and the target dimensions. I think this is what happened with the lowering Pattern for memref.transpose:
https://github.com/llvm/llvm-project/blob/main/mlir/lib/Conversion/MemRefToLLVM/MemRefToLLVM.cpp#L1562

For the testcase to demonstrate the problem I will use the textual representation of verified Ops where it is clear what the shape and strides should be as the reference:

test.mlir:

func.func @transpose(%arg0: memref<1x2x3xf32, strided<[6, 3, 1], offset: ?>>) -> memref<3x1x2xf32, strided<[1, 6, 3], offset: ?>> {
  %0 = memref.transpose %arg0 (i, j, k) -> (k, i, j) : memref<1x2x3xf32, strided<[6, 3, 1], offset: ?>> to memref<3x1x2xf32, strided<[1, 6, 3], offset: ?>>
  return %0 : memref<3x1x2xf32, strided<[1, 6, 3], offset: ?>>
}

test.cpp:

#include <mlir/ExecutionEngine/CRunnerUtils.h>
#include <iostream>

extern "C" void _mlir_ciface_transpose(StridedMemRefType<float, 3> *, StridedMemRefType<float, 3> *);

int main() {
    StridedMemRefType<float, 3> in, out;

    in.sizes[0] = 1;
    in.sizes[1] = 2;
    in.sizes[2] = 3;
    in.strides[0] = 6;
    in.strides[1] = 3;
    in.strides[2] = 1;
    _mlir_ciface_transpose(&out, &in);

    std::cout << "output has sizes: [" << out.sizes[0] << ", " << 
        out.sizes[1] << ", " <<  out.sizes[2] << "] strides : [" << out.strides[0] << ", " << 
        out.strides[1] << ", " << out.strides[2] << "]\n";
    return 0;
}
$ mlir-opt --normalize-memrefs --memref-expand --finalize-memref-to-llvm --llvm-request-c-wrappers --convert-func-to-llvm --reconcile-unrealized-casts --llvm-legalize-for-export test.mlir -o test.llvm.mlir
$ mlir-translate --mlir-to-llvmir test.llvm.mlir -o test.ll
$ clang++-17 -I/mnt/build_llvm/llvm-project/mlir/include/ test.cpp test.ll
warning: overriding the module target triple with x86_64-pc-linux-gnu [-Woverride-module]
1 warning generated.
$ ./a.out 
output has sizes: [2, 3, 1] strides : [3, 1, 6]

We can see that instead of doing the (i,j,k)->(k,i,j) transposition, the lowering pass actually did it the other way around, i.e. (k,i,j)->(i,j,k).

@ubfx
Copy link
Member Author

ubfx commented Aug 31, 2023

Phabricator: https://reviews.llvm.org/D159290

@nicolasvasilache
Copy link
Contributor

It would also make sense to update the affine map representation to a list of integers if you are up for it.
We did a similar change to collapse/expand_shape for the same reason.

Thanks for fixing!

@ubfx
Copy link
Member Author

ubfx commented Aug 31, 2023

Good idea! I will have a look and try to apply the integer notation to memref.transpose

@ftynse ftynse closed this as completed in 55088ef Sep 14, 2023
kstoimenov pushed a commit to kstoimenov/llvm-project that referenced this issue Sep 14, 2023
The lowering pattern to LLVM for memref.transpose has a bug where
instead of transposing from (source) -> (dest) it actually transposes
(dest) -> (source). This patch fixes the bug and updates the test.

Fix llvm#65145

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D159290
ZijunZhaoCCK pushed a commit to ZijunZhaoCCK/llvm-project that referenced this issue Sep 19, 2023
The lowering pattern to LLVM for memref.transpose has a bug where
instead of transposing from (source) -> (dest) it actually transposes
(dest) -> (source). This patch fixes the bug and updates the test.

Fix llvm#65145

Reviewed By: nicolasvasilache

Differential Revision: https://reviews.llvm.org/D159290
ubfx added a commit to ubfx/llvm-project that referenced this issue Sep 30, 2023
…ef.transpose

Until now, the dimensional permutation for memref.transpose was given in the
form of an affine map. However, just from looking at such a representation,
e.g. `(i, j) -> (j, i)`, it's not obvious whether it represents a mapping from
the result dimensions to the source dimensions or the other way around. This has
led to a bug (llvm#65145).

This patch introduces to `memref.transpose` the integer array based notation
that is also used in Ops like `linalg.transpose`, `memref.collapse_shape`
and others which is harder to misinterpret and easier to work with.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants