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

Error compiling code with Polygeist: 'affine.for' op operand cannot be used as a symbol #398

Open
CristianTirelli opened this issue Apr 10, 2024 · 0 comments

Comments

@CristianTirelli
Copy link

Hi all,

I was playing with Polygeist and after writing on the discord channel they suggested me to post my issue here, since it could be a bug.

This is the code I'm trying to compile:

    data_t V[N][N];
    data_t U_tmp[N][N];
    data_t L_tmp[N][N];

    for (int k = 0; k < 32; k++) {    
      for (int j = k; j < 32; j++)
        for (int i = k*k; i < 32; i++) {
          if (k == 0)
            prev_V[i*j][j] = A[i][j];
          else
            prev_V[i][j] = V[i][j];          

          if (j == k) {          
            U_tmp[i][j] = prev_V[i][j]; 
            U[j][i] = U_tmp[i][j]; // final
          } else {          
            U_tmp[i][j] = U_tmp[i][j - 1];        

            if (i == k) {
              L_tmp[i][j] = prev_V[i][j] / U_tmp[i][j]; 
              L[i][j] = L_tmp[i][j]; // final
            } else {            
              L_tmp[i][j] = L_tmp[i - 1][j];
            }          
          
            V[i][j] = prev_V[i][j] - L_tmp[i][j] * U_tmp[i][j];
          }

        }
    }

with the command : cgeist --function=lu_device -S kernel.c

The error I get is:

...kernel.c":75:9): error: 'affine.for' op operand cannot be used as a symbol
"builtin.module"() ({
  "func.func"() <{function_type = (memref<?x32xf32>, memref<?x32xf32>, memref<?x32xf32>) -> (), sym_name = "lu_device"}> ({
  ^bb0(%arg0: memref<?x32xf32>, %arg1: memref<?x32xf32>, %arg2: memref<?x32xf32>):
    %0 = "memref.alloca"() <{operandSegmentSizes = array<i32: 0, 0>}> : () -> memref<32x32xf32>
    %1 = "memref.alloca"() <{operandSegmentSizes = array<i32: 0, 0>}> : () -> memref<32x32xf32>
    %2 = "memref.alloca"() <{operandSegmentSizes = array<i32: 0, 0>}> : () -> memref<32x32xf32>
    %3 = "memref.alloca"() <{operandSegmentSizes = array<i32: 0, 0>}> : () -> memref<32x32xf32>
    "affine.for"() ({
    ^bb0(%arg3: index):
      %4 = "arith.index_cast"(%arg3) : (index) -> i32
      %5 = "arith.muli"(%4, %4) : (i32, i32) -> i32
      %6 = "arith.index_cast"(%5) : (i32) -> index
      "affine.for"(%arg3) ({
      ^bb0(%arg4: index):
        %7 = "arith.index_cast"(%arg4) : (index) -> i32
        "affine.for"(%6) ({
        ^bb0(%arg5: index):
          %8 = "arith.index_cast"(%arg5) : (index) -> i32
          "affine.if"(%arg3) ({
            %9 = "arith.muli"(%8, %7) : (i32, i32) -> i32
            %10 = "arith.index_cast"(%9) : (i32) -> index
            %11 = "affine.load"(%arg0, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (memref<?x32xf32>, index, index) -> f32
            "memref.store"(%11, %3, %10, %arg4) <{nontemporal = false}> : (f32, memref<32x32xf32>, index, index) -> ()
            "affine.yield"() : () -> ()
          }, {
            %9 = "affine.load"(%2, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (memref<32x32xf32>, index, index) -> f32
            "affine.store"(%9, %3, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<32x32xf32>, index, index) -> ()
            "affine.yield"() : () -> ()
          }) {condition = affine_set<(d0) : (d0 == 0)>} : (index) -> ()
          "affine.if"(%arg4, %arg3) ({
            %9 = "affine.load"(%3, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (memref<32x32xf32>, index, index) -> f32
            "affine.store"(%9, %1, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<32x32xf32>, index, index) -> ()
            "affine.store"(%9, %arg2, %arg4, %arg5) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<?x32xf32>, index, index) -> ()
            "affine.yield"() : () -> ()
          }, {
            %9 = "affine.load"(%1, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1 - 1)>}> : (memref<32x32xf32>, index, index) -> f32
            "affine.store"(%9, %1, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<32x32xf32>, index, index) -> ()
            %10 = "affine.if"(%arg5, %arg3) ({
              %14 = "affine.load"(%3, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (memref<32x32xf32>, index, index) -> f32
              %15 = "arith.divf"(%14, %9) <{fastmath = #arith.fastmath<none>}> : (f32, f32) -> f32
              "affine.store"(%15, %0, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<32x32xf32>, index, index) -> ()
              "affine.store"(%15, %arg1, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<?x32xf32>, index, index) -> ()
              "affine.yield"(%15) : (f32) -> ()
            }, {
              %14 = "affine.load"(%0, %arg4, %arg5) <{map = affine_map<(d0, d1) -> (d1 - 1, d0)>}> : (memref<32x32xf32>, index, index) -> f32
              "affine.store"(%14, %0, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<32x32xf32>, index, index) -> ()
              "affine.yield"(%14) : (f32) -> ()
            }) {condition = affine_set<(d0, d1) : (d0 - d1 == 0)>} : (index, index) -> f32
            %11 = "affine.load"(%3, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (memref<32x32xf32>, index, index) -> f32
            %12 = "arith.mulf"(%10, %9) <{fastmath = #arith.fastmath<none>}> : (f32, f32) -> f32
            %13 = "arith.subf"(%11, %12) <{fastmath = #arith.fastmath<none>}> : (f32, f32) -> f32
            "affine.store"(%13, %2, %arg5, %arg4) <{map = affine_map<(d0, d1) -> (d0, d1)>}> : (f32, memref<32x32xf32>, index, index) -> ()
            "affine.yield"() : () -> ()
          }) {condition = affine_set<(d0, d1) : (d0 - d1 == 0)>} : (index, index) -> ()
          "affine.yield"() : () -> ()
        }) {lower_bound = affine_map<()[s0] -> (s0)>, step = 1 : index, upper_bound = affine_map<() -> (32)>} : (index) -> ()
        "affine.yield"() : () -> ()
      }) {lower_bound = affine_map<(d0) -> (d0)>, step = 1 : index, upper_bound = affine_map<() -> (32)>} : (index) -> ()
      "affine.yield"() : () -> ()
    }) {lower_bound = affine_map<() -> (0)>, step = 1 : index, upper_bound = affine_map<() -> (32)>} : () -> ()
    "func.return"() : () -> ()
  }) {llvm.linkage = #llvm.linkage<external>} : () -> ()
}) {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<i8, dense<8> : vector<2xi32>>, #dlti.dl_entry<i16, dense<16> : vector<2xi32>>, #dlti.dl_entry<i1, dense<8> : vector<2xi32>>, #dlti.dl_entry<i32, dense<32> : vector<2xi32>>, #dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi32>>, #dlti.dl_entry<f16, dense<16> : vector<2xi32>>, #dlti.dl_entry<f64, dense<64> : vector<2xi32>>, #dlti.dl_entry<f128, dense<128> : vector<2xi32>>, #dlti.dl_entry<f80, dense<128> : vector<2xi32>>, #dlti.dl_entry<i64, dense<64> : vector<2xi32>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi32>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi32>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi32>>, #dlti.dl_entry<"dlti.stack_alignment", 128 : i32>, #dlti.dl_entry<"dlti.endianness", "little">>, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu", "polygeist.target-cpu" = "x86-64", "polygeist.target-features" = "+cmov,+cx8,+fxsr,+mmx,+sse,+sse2,+x87", "polygeist.tune-cpu" = "generic"} : () -> ()

If I remove the k*k from the c code then everything works fine. Is this intended behavior? Looks like cgreist automatically tries to lower to affine and if it can't then it crashes.

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

No branches or pull requests

1 participant