Error compiling code with Polygeist: 'affine.for' op operand cannot be used as a symbol
Nobody has claimed this yet.
- Dominant language
- C++
- Stars
- 624
- Forks
- 170
- PR merge metrics
- No merged PRs in 30d
Description
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 prev_V[N][N];
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, memref, memref) -> (), sym_name = "lu_device"}> ({
^bb0(%arg0: memref, %arg1: memref, %arg2: memref):
%0 = "memref.alloca"() <{operandSegmentSizes = array}> : () -> memref<32x32xf32>
%1 = "memref.alloca"() <{operandSegmentSizes = array}> : () -> memref<32x32xf32>
%2 = "memref.alloca"() <{operandSegmentSizes = array}> : () -> memref<32x32xf32>
%3 = "memref.alloca"() <{operandSegmentSizes = array}> : () -> 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, 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, 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}> : (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, 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}> : (f32, f32) -> f32
%13 = "arith.subf"(%11, %12) <{fastmath = #arith.fastmath}> : (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} : () -> ()
}) {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<4xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry : vector<2xi32>>, #dlti.dl_entry, dense<64> : vector<4xi32>>, #dlti.dl_entry, dense<32> : vector<4xi32>>, #dlti.dl_entry, 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.
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the failure with the code in kernel.c using `cgeist --function=lu_device -S kernel.c`, then inspect the generated affine.for operations around the `k*k` lower bound. Compare this with the version where `k*k` is removed; done means the compiler handles the expression without reporting that an affine.for operand cannot be used as a symbol.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- c, cpp
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100