|
5 | 5 | from mlir.dialects import arith
|
6 | 6 | from mlir.dialects import memref
|
7 | 7 | from mlir.dialects import affine
|
| 8 | +import mlir.extras.types as T |
8 | 9 |
|
9 | 10 |
|
10 | 11 | def constructAndPrintInModule(f):
|
@@ -107,66 +108,151 @@ def affine_for_op_test(buffer):
|
107 | 108 | # CHECK: %[[TMP:.*]] = memref.load %[[BUFFER]][%[[INDVAR]]] : memref<1024xf32>
|
108 | 109 | tmp = memref.LoadOp(buffer, [sum.induction_variable])
|
109 | 110 | sum_next = arith.AddFOp(sum.inner_iter_args[0], tmp)
|
110 |
| - |
111 | 111 | affine.AffineYieldOp([sum_next])
|
112 | 112 |
|
113 |
| - return |
| 113 | + |
| 114 | +# CHECK-LABEL: TEST: testAffineForOpErrors |
| 115 | +@constructAndPrintInModule |
| 116 | +def testAffineForOpErrors(): |
| 117 | + c1 = arith.ConstantOp(T.index(), 1) |
| 118 | + c2 = arith.ConstantOp(T.index(), 2) |
| 119 | + c3 = arith.ConstantOp(T.index(), 3) |
| 120 | + d0 = AffineDimExpr.get(0) |
| 121 | + |
| 122 | + try: |
| 123 | + affine.AffineForOp( |
| 124 | + c1, |
| 125 | + c2, |
| 126 | + 1, |
| 127 | + lower_bound_operands=[c3], |
| 128 | + upper_bound_operands=[], |
| 129 | + ) |
| 130 | + except ValueError as e: |
| 131 | + assert ( |
| 132 | + e.args[0] |
| 133 | + == "Either a concrete lower bound or an AffineMap in combination with lower bound operands, but not both, is supported." |
| 134 | + ) |
| 135 | + |
| 136 | + try: |
| 137 | + affine.AffineForOp( |
| 138 | + AffineMap.get_constant(1), |
| 139 | + c2, |
| 140 | + 1, |
| 141 | + lower_bound_operands=[c3, c3], |
| 142 | + upper_bound_operands=[], |
| 143 | + ) |
| 144 | + except ValueError as e: |
| 145 | + assert ( |
| 146 | + e.args[0] |
| 147 | + == "Wrong number of lower bound operands passed to AffineForOp; Expected 0, got 2." |
| 148 | + ) |
| 149 | + |
| 150 | + try: |
| 151 | + two_indices = affine.AffineDelinearizeIndexOp( |
| 152 | + [T.index(), T.index()], c1, [c1, c1] |
| 153 | + ) |
| 154 | + affine.AffineForOp( |
| 155 | + two_indices, |
| 156 | + c2, |
| 157 | + 1, |
| 158 | + lower_bound_operands=[], |
| 159 | + upper_bound_operands=[], |
| 160 | + ) |
| 161 | + except ValueError as e: |
| 162 | + assert e.args[0] == "Only a single concrete value is supported for lower bound." |
| 163 | + |
| 164 | + try: |
| 165 | + affine.AffineForOp( |
| 166 | + 1.0, |
| 167 | + c2, |
| 168 | + 1, |
| 169 | + lower_bound_operands=[], |
| 170 | + upper_bound_operands=[], |
| 171 | + ) |
| 172 | + except ValueError as e: |
| 173 | + assert e.args[0] == "lower bound must be int | ResultValueT | AffineMap." |
114 | 174 |
|
115 | 175 |
|
116 | 176 | @constructAndPrintInModule
|
117 | 177 | def testForSugar():
|
118 |
| - index_type = IndexType.get() |
119 |
| - memref_t = MemRefType.get([10], index_type) |
| 178 | + memref_t = T.memref(10, T.index()) |
120 | 179 | range = affine.for_
|
121 | 180 |
|
122 |
| - # CHECK: func.func @range_loop_1(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: memref<10xindex>) { |
123 |
| - # CHECK: %[[VAL_4:.*]] = arith.constant 10 : index |
124 |
| - # CHECK: affine.for %[[VAL_6:.*]] = %[[VAL_0]] to %[[VAL_4]] step 2 { |
125 |
| - # CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_6]], %[[VAL_6]] : index |
126 |
| - # CHECK: affine.store %[[VAL_7]], %[[VAL_3]]{{\[symbol\(}}%[[VAL_6]]{{\)\]}} : memref<10xindex> |
127 |
| - # CHECK: } |
128 |
| - # CHECK: return |
129 |
| - # CHECK: } |
130 |
| - @func.FuncOp.from_py_func(index_type, index_type, index_type, memref_t) |
131 |
| - def range_loop_1(lb, ub, step, memref_v): |
132 |
| - for i in range(lb, 10, 2): |
| 181 | + # CHECK: #[[$ATTR_2:.+]] = affine_map<(d0) -> (d0)> |
| 182 | + |
| 183 | + # CHECK-LABEL: func.func @range_loop_1( |
| 184 | + # CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: memref<10xindex>) { |
| 185 | + # CHECK: affine.for %[[VAL_3:.*]] = #[[$ATTR_2]](%[[VAL_0]]) to #[[$ATTR_2]](%[[VAL_1]]) { |
| 186 | + # CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_3]] : index |
| 187 | + # CHECK: memref.store %[[VAL_4]], %[[VAL_2]]{{\[}}%[[VAL_3]]] : memref<10xindex> |
| 188 | + # CHECK: } |
| 189 | + # CHECK: return |
| 190 | + # CHECK: } |
| 191 | + @func.FuncOp.from_py_func(T.index(), T.index(), memref_t) |
| 192 | + def range_loop_1(lb, ub, memref_v): |
| 193 | + for i in range(lb, ub, step=1): |
133 | 194 | add = arith.addi(i, i)
|
134 |
| - s0 = AffineSymbolExpr.get(0) |
135 |
| - map = AffineMap.get(0, 1, [s0]) |
136 |
| - affine.store(add, memref_v, [i], map=map) |
137 |
| - affine.AffineYieldOp([]) |
138 |
| - |
139 |
| - # CHECK: func.func @range_loop_2(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: memref<10xindex>) { |
140 |
| - # CHECK: %[[VAL_4:.*]] = arith.constant 0 : index |
141 |
| - # CHECK: %[[VAL_5:.*]] = arith.constant 10 : index |
142 |
| - # CHECK: affine.for %[[VAL_7:.*]] = %[[VAL_4]] to %[[VAL_5]] { |
143 |
| - # CHECK: %[[VAL_8:.*]] = arith.addi %[[VAL_7]], %[[VAL_7]] : index |
144 |
| - # CHECK: affine.store %[[VAL_8]], %[[VAL_3]]{{\[symbol\(}}%[[VAL_7]]{{\)\]}} : memref<10xindex> |
145 |
| - # CHECK: } |
146 |
| - # CHECK: return |
147 |
| - # CHECK: } |
148 |
| - @func.FuncOp.from_py_func(index_type, index_type, index_type, memref_t) |
149 |
| - def range_loop_2(lb, ub, step, memref_v): |
150 |
| - for i in range(0, 10, 1): |
| 195 | + memref.store(add, memref_v, [i]) |
| 196 | + |
| 197 | + affine.yield_([]) |
| 198 | + |
| 199 | + # CHECK-LABEL: func.func @range_loop_2( |
| 200 | + # CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: memref<10xindex>) { |
| 201 | + # CHECK: affine.for %[[VAL_3:.*]] = #[[$ATTR_2]](%[[VAL_0]]) to 10 { |
| 202 | + # CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_3]] : index |
| 203 | + # CHECK: memref.store %[[VAL_4]], %[[VAL_2]]{{\[}}%[[VAL_3]]] : memref<10xindex> |
| 204 | + # CHECK: } |
| 205 | + # CHECK: return |
| 206 | + # CHECK: } |
| 207 | + @func.FuncOp.from_py_func(T.index(), T.index(), memref_t) |
| 208 | + def range_loop_2(lb, ub, memref_v): |
| 209 | + for i in range(lb, 10, step=1): |
151 | 210 | add = arith.addi(i, i)
|
152 |
| - s0 = AffineSymbolExpr.get(0) |
153 |
| - map = AffineMap.get(0, 1, [s0]) |
154 |
| - affine.store(add, memref_v, [i], map=map) |
155 |
| - affine.AffineYieldOp([]) |
156 |
| - |
157 |
| - # CHECK: func.func @range_loop_3(%[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: index, %[[VAL_3:.*]]: memref<10xindex>) { |
158 |
| - # CHECK: %[[VAL_4:.*]] = arith.constant 0 : index |
159 |
| - # CHECK: affine.for %[[VAL_6:.*]] = %[[VAL_4]] to %[[VAL_1]] { |
160 |
| - # CHECK: %[[VAL_7:.*]] = arith.addi %[[VAL_6]], %[[VAL_6]] : index |
161 |
| - # CHECK: affine.store %[[VAL_7]], %[[VAL_3]]{{\[symbol\(}}%[[VAL_6]]{{\)\]}} : memref<10xindex> |
162 |
| - # CHECK: } |
163 |
| - # CHECK: return |
164 |
| - # CHECK: } |
165 |
| - @func.FuncOp.from_py_func(index_type, index_type, index_type, memref_t) |
166 |
| - def range_loop_3(lb, ub, step, memref_v): |
167 |
| - for i in range(0, ub, 1): |
| 211 | + memref.store(add, memref_v, [i]) |
| 212 | + affine.yield_([]) |
| 213 | + |
| 214 | + # CHECK-LABEL: func.func @range_loop_3( |
| 215 | + # CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: memref<10xindex>) { |
| 216 | + # CHECK: affine.for %[[VAL_3:.*]] = 0 to #[[$ATTR_2]](%[[VAL_1]]) { |
| 217 | + # CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_3]] : index |
| 218 | + # CHECK: memref.store %[[VAL_4]], %[[VAL_2]]{{\[}}%[[VAL_3]]] : memref<10xindex> |
| 219 | + # CHECK: } |
| 220 | + # CHECK: return |
| 221 | + # CHECK: } |
| 222 | + @func.FuncOp.from_py_func(T.index(), T.index(), memref_t) |
| 223 | + def range_loop_3(lb, ub, memref_v): |
| 224 | + for i in range(0, ub, step=1): |
| 225 | + add = arith.addi(i, i) |
| 226 | + memref.store(add, memref_v, [i]) |
| 227 | + affine.yield_([]) |
| 228 | + |
| 229 | + # CHECK-LABEL: func.func @range_loop_4( |
| 230 | + # CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: memref<10xindex>) { |
| 231 | + # CHECK: affine.for %[[VAL_3:.*]] = 0 to 10 { |
| 232 | + # CHECK: %[[VAL_4:.*]] = arith.addi %[[VAL_3]], %[[VAL_3]] : index |
| 233 | + # CHECK: memref.store %[[VAL_4]], %[[VAL_2]]{{\[}}%[[VAL_3]]] : memref<10xindex> |
| 234 | + # CHECK: } |
| 235 | + # CHECK: return |
| 236 | + # CHECK: } |
| 237 | + @func.FuncOp.from_py_func(T.index(), T.index(), memref_t) |
| 238 | + def range_loop_4(lb, ub, memref_v): |
| 239 | + for i in range(0, 10, step=1): |
| 240 | + add = arith.addi(i, i) |
| 241 | + memref.store(add, memref_v, [i]) |
| 242 | + affine.yield_([]) |
| 243 | + |
| 244 | + # CHECK-LABEL: func.func @range_loop_8( |
| 245 | + # CHECK-SAME: %[[VAL_0:.*]]: index, %[[VAL_1:.*]]: index, %[[VAL_2:.*]]: memref<10xindex>) { |
| 246 | + # CHECK: %[[VAL_3:.*]] = affine.for %[[VAL_4:.*]] = 0 to 10 iter_args(%[[VAL_5:.*]] = %[[VAL_2]]) -> (memref<10xindex>) { |
| 247 | + # CHECK: %[[VAL_6:.*]] = arith.addi %[[VAL_4]], %[[VAL_4]] : index |
| 248 | + # CHECK: memref.store %[[VAL_6]], %[[VAL_5]]{{\[}}%[[VAL_4]]] : memref<10xindex> |
| 249 | + # CHECK: affine.yield %[[VAL_5]] : memref<10xindex> |
| 250 | + # CHECK: } |
| 251 | + # CHECK: return |
| 252 | + # CHECK: } |
| 253 | + @func.FuncOp.from_py_func(T.index(), T.index(), memref_t) |
| 254 | + def range_loop_8(lb, ub, memref_v): |
| 255 | + for i, it in range(0, 10, iter_args=[memref_v]): |
168 | 256 | add = arith.addi(i, i)
|
169 |
| - s0 = AffineSymbolExpr.get(0) |
170 |
| - map = AffineMap.get(0, 1, [s0]) |
171 |
| - affine.store(add, memref_v, [i], map=map) |
172 |
| - affine.AffineYieldOp([]) |
| 257 | + memref.store(add, it, [i]) |
| 258 | + affine.yield_([it]) |
0 commit comments