llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
27.96k stars 11.53k forks source link

[mlir] crash in memref.copy #56914

Open MiraaChan opened 2 years ago

MiraaChan commented 2 years ago

Hi, I was running this mlir with mlir-cpu-runner.

#map0 = affine_map<(d0, d1)[s0] -> (d0 * 128 + s0 + d1)>
#map1 = affine_map<(d0, d1)[s0, s1] -> (d0 * s1 + s0 + d1)>
module {
  func.func @matmul(%arg0: memref<128x128xf32>, %arg1: memref<128x128xf32>, %arg2: memref<128x128xf32>) attributes {llvm.emit_c_interface} {
    %cst = arith.constant 0.000000e+00 : f32
    linalg.fill ins(%cst : f32) outs(%arg2 : memref<128x128xf32>)
    %c0 = arith.constant 0 : index
    %c128 = arith.constant 128 : index
    %c8 = arith.constant 8 : index
    %c4 = arith.constant 4 : index
    %c16 = arith.constant 16 : index
    scf.for %arg3 = %c0 to %c128 step %c8 {
      scf.for %arg4 = %c0 to %c128 step %c4 {
        scf.for %arg5 = %c0 to %c128 step %c16 {
          %0 = memref.subview %arg0[%arg3, %arg4] [8, 4] [1, 1] : memref<128x128xf32> to memref<8x4xf32, #map0>
          %1 = memref.subview %arg1[%arg4, %arg5] [4, 16] [1, 1] : memref<128x128xf32> to memref<4x16xf32, #map0>
          %2 = memref.subview %arg2[%arg3, %arg5] [8, 16] [1, 1] : memref<128x128xf32> to memref<8x16xf32, #map0>
          %c2 = arith.constant 2 : index
          scf.for %arg6 = %c0 to %c8 step %c2 {
            scf.for %arg7 = %c0 to %c16 step %c4 {
              %3 = memref.subview %0[%arg6, 0] [2, 4] [1, 1] : memref<8x4xf32, #map0> to memref<2x4xf32, #map0>
              %4 = memref.subview %1[0, %arg7] [4, 4] [1, 1] : memref<4x16xf32, #map0> to memref<4x4xf32, #map0>
              %5 = memref.subview %2[%arg6, %arg7] [2, 4] [1, 1] : memref<8x16xf32, #map0> to memref<2x4xf32, #map0>
              %6 = memref.alloc() : memref<32xi8>
              %7 = memref.view %6[%c0][%c2, %c4] : memref<32xi8> to memref<?x?xf32>
              %8 = memref.subview %7[0, 0] [%c2, %c4] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #map1>
              %9 = memref.alloc() : memref<32xi8>
              %10 = memref.view %9[%c0][%c2, %c4] : memref<32xi8> to memref<?x?xf32>
              %11 = memref.subview %10[0, 0] [%c2, %c4] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #map1>
              memref.copy %3, %8 : memref<2x4xf32, #map0> to memref<?x?xf32, #map1>
              memref.copy %5, %11 : memref<2x4xf32, #map0> to memref<?x?xf32, #map1>
              linalg.matmul ins(%8, %4 : memref<?x?xf32, #map1>, memref<4x4xf32, #map0>) outs(%11 : memref<?x?xf32, #map1>)
              memref.copy %11, %5 : memref<?x?xf32, #map1> to memref<2x4xf32, #map0>
              memref.dealloc %6 : memref<32xi8>
              memref.dealloc %9 : memref<32xi8>
            }
          }
        }
      }
    }
    return
  }
  func.func @main() {
    %cst = arith.constant 1.000000e+00 : f32
    %cst_0 = arith.constant 1.280000e+02 : f32
    %c0 = arith.constant 0 : index
    %c1 = arith.constant 1 : index
    %c128 = arith.constant 128 : index
    %0 = memref.alloc() : memref<128x128xf32>
    %1 = memref.alloc() : memref<128x128xf32>
    %2 = memref.alloc() : memref<128x128xf32>
    linalg.fill ins(%cst : f32) outs(%0 : memref<128x128xf32>)
    linalg.fill ins(%cst : f32) outs(%1 : memref<128x128xf32>)
    call @matmul(%2, %0, %1) : (memref<128x128xf32>, memref<128x128xf32>, memref<128x128xf32>) -> ()
    scf.for %arg0 = %c0 to %c128 step %c1 {
      scf.for %arg1 = %c0 to %c128 step %c1 {
        %3 = memref.load %2[%arg0, %arg1] : memref<128x128xf32>
        %4 = arith.cmpf oeq, %3, %cst_0 : f32
        cf.assert %4, "Matmul does not produce the right output"
      }
    }
    memref.dealloc %0 : memref<128x128xf32>
    memref.dealloc %1 : memref<128x128xf32>
    memref.dealloc %2 : memref<128x128xf32>
    return
  }
}

The command is

mlir-opt copy_test.mlir -pass-pipeline="func.func(convert-linalg-to-loops,convert-scf-to-cf,convert-arith-to-llvm),convert-linalg-to-llvm,convert-memref-to-llvm,convert-func-to-llvm,reconcile-unrealized-casts" | \
mlir-cpu-runner -e main -entry-point-result=void \
-shared-libs=/data/3rdparty/llvm-project/build/lib/libmlir_runner_utils.so,/data/3rdparty/llvm-project/build/lib/libmlir_c_runner_utils.so

And it crashed with:

Stack dump:
0.      Program arguments: mlir-cpu-runner -e main -entry-point-result=void -shared-libs=/data/3rdparty/llvm-project/build/lib/libmlir_runner_utils.so,/data/3rdparty/llvm-project/build/lib/libmlir_c_runner_utils.so
 #0 0x000055d56f369ee0 PrintStackTraceSignalHandler(void*) (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x2aaee0)
 #1 0x000055d56f367904 SignalHandler(int) (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x2a8904)
 #2 0x00007f2c180a2980 __restore_rt (/lib/x86_64-linux-gnu/libpthread.so.0+0x12980)
 #3 0x00007f2c0ece9bf0 memrefCopy (/data/3rdparty/llvm-project/build/lib/libmlir_c_runner_utils.so+0x18bf0)
 #4 0x00007f2c184cd229
 #5 0x00007f2c184cd604
 #6 0x00007f2c184cd7ed
 #7 0x000055d56f83dedc compileAndExecute((anonymous namespace)::Options&, mlir::ModuleOp, llvm::StringRef, (anonymous namespace)::CompileAndExecuteConfig, void**) (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x77eedc)
 #8 0x000055d56f83e37a compileAndExecuteVoidFunction((anonymous namespace)::Options&, mlir::ModuleOp, llvm::StringRef, (anonymous namespace)::CompileAndExecuteConfig) (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x77f37a)
 #9 0x000055d56f841a82 mlir::JitRunnerMain(int, char**, mlir::DialectRegistry const&, mlir::JitRunnerConfig) (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x782a82)
#10 0x000055d56f2e1629 main (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x222629)
#11 0x00007f2c16cb2c87 __libc_start_main /build/glibc-uZu3wS/glibc-2.27/csu/../csu/libc-start.c:344:0
#12 0x000055d56f34ed1a _start (/data/3rdparty/llvm-project/build/bin/mlir-cpu-runner+0x28fd1a)
[1]    13928 done                mlir-opt copy_test.mlir  |
       13929 segmentation fault  mlir-cpu-runner -e main -entry-point-result=void

the commit id of my llvm is e0a3964affe82a63702e231c84be535d39413d1b, any help would be appreciated.

MiraaChan commented 2 years ago

When I tried to debug, I found this: Normally, memrefCopy will end with "axis == 0" return true. But the crashed case is that the src_arg which passed to memrefCopy is illegal, so it can't normally end with "axis = 0" and when it comes with any action with src_arg, such as I tried to print the meta data of src_arg when entering the memrefCopy:

printMemRefMetaData(std::cout, DynamicMemRefType<char>(*src_arg));

it will crash after a few loops.

I guess, it was something wrong with the memref lowering.

llvmbot commented 2 years ago

@llvm/issue-subscribers-mlir

MiraaChan commented 2 years ago

@fhahn hi, sorry to bother, do you have any ideas about what might be the cause of the problem?