1// RUN: mlir-opt %s -test-linalg-transform-patterns=test-patterns | FileCheck %s 2 3// CHECK-DAG: #[[$STRIDED_1D:.*]] = affine_map<(d0)[s0] -> (d0 + s0)> 4// Map corresponding to a 2D memory access where the stride along the last dim is known to be 1. 5// CHECK-DAG: #[[$STRIDED_2D_u_1:.*]] = affine_map<(d0, d1)[s0, s1] -> (d0 * s1 + s0 + d1)> 6// Map corresponding to a 2D memory access where the stride along all dims are unknown. 7// CHECK-DAG: #[[$STRIDED_2D:.*]] = affine_map<(d0, d1)[s0, s1, s2] -> (d0 * s1 + s0 + d1 * s2)> 8// CHECK-DAG: #[[$kn:.*]] = affine_map<(d0, d1, d2) -> (d2, d1)> 9// CHECK-DAG: #[[$nm:.*]] = affine_map<(d0, d1, d2) -> (d1, d0)> 10// CHECK-DAG: #[[$km:.*]] = affine_map<(d0, d1, d2) -> (d2, d0)> 11 12func @dot(%x: memref<?xf32, offset: ?, strides: [1]>, 13 %y: memref<?xf32, offset: ?, strides: [1]>, 14 %v: memref<f32>) { 15 linalg.dot { __internal_linalg_transform__ = "MEM" } 16 ins(%x, %y: memref<?xf32, offset: ?, strides: [1]>, 17 memref<?xf32, offset: ?, strides: [1]>) 18 outs(%v: memref<f32>) 19 20 return 21} 22// CHECK-LABEL: func @dot 23// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 24// CHECK-DAG: %[[c1:.*]] = arith.constant 1 : index 25// CHECK-DAG: %[[c8000:.*]] = arith.constant 8000 : index 26// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c8000]] { 27// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c1]] { 28// CHECK: load 29// CHECK: load 30// CHECK: load 31// CHECK: arith.mulf 32// CHECK: arith.addf 33// CHECK: store 34 35func @matvec(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 36 %x: memref<?xf32, offset: ?, strides: [1]>, 37 %y: memref<?xf32, offset: ?, strides: [1]>) { 38 linalg.matvec 39 ins(%A, %x: memref<?x?xf32, offset: ?, strides: [?, 1]>, 40 memref<?xf32, offset: ?, strides: [1]>) 41 outs(%y: memref<?xf32, offset: ?, strides: [1]>) 42 return 43} 44// CHECK-LABEL: func @matvec 45// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 46// CHECK-DAG: %[[c5:.*]] = arith.constant 5 : index 47// CHECK-DAG: %[[c6:.*]] = arith.constant 6 : index 48// CHECK: scf.parallel {{.*}} step (%[[c5]]) 49// CHECK: scf.for {{.*}} step %[[c6]] 50// CHECK: linalg.matvec 51// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>) 52// CHECK: outs({{.*}}: memref<?xf32, #[[$STRIDED_1D]]>) 53 54func @matmul(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 55 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 56 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 57 linalg.matmul { __internal_linalg_transform__ = "MEM" } 58 ins(%A, %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 59 memref<?x?xf32, offset: ?, strides: [?, 1]>) 60 outs(%C: memref<?x?xf32, offset: ?, strides: [?, 1]>) 61 return 62} 63// CHECK-LABEL: func @matmul 64// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 65// CHECK-DAG: %[[c2:.*]] = arith.constant 2 : index 66// CHECK-DAG: %[[c3:.*]] = arith.constant 3 : index 67// CHECK-DAG: %[[c4:.*]] = arith.constant 4 : index 68// CHECK-DAG: %[[c20:.*]] = arith.constant 20 : index 69// CHECK-DAG: %[[c30:.*]] = arith.constant 30 : index 70// CHECK-DAG: %[[c40:.*]] = arith.constant 40 : index 71// CHECK-DAG: %[[c200:.*]] = arith.constant 200 : index 72// CHECK-DAG: %[[c300:.*]] = arith.constant 300 : index 73// CHECK-DAG: %[[c400:.*]] = arith.constant 400 : index 74// CHECK-DAG: %[[c2000:.*]] = arith.constant 2000 : index 75// CHECK-DAG: %[[c3000:.*]] = arith.constant 3000 : index 76// CHECK-DAG: %[[c4000:.*]] = arith.constant 4000 : index 77// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 78// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 79// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 80// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c200]] { 81// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c300]] { 82// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c400]] { 83// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c20]] { 84// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c30]] { 85// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c40]] { 86// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2]] { 87// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3]] { 88// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4]] { 89// CHECK: linalg.matmul 90// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 91// CHECK: outs({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 92 93#matmul_accesses = [ 94 affine_map<(m, n, k) -> (m, k)>, 95 affine_map<(m, n, k) -> (k, n)>, 96 affine_map<(m, n, k) -> (m, n)> 97] 98#generic_matmul_trait = { 99 args_in = 2, 100 args_out = 1, 101 indexing_maps = #matmul_accesses, 102 library_call = "linalg_matmul", 103 iterator_types = ["parallel", "parallel", "reduction"] 104} 105func @permute_generic(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 106 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 107 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 108 linalg.generic #generic_matmul_trait 109 ins(%A, %B : memref<?x?xf32, offset: ?, strides: [?, 1]>, 110 memref<?x?xf32, offset: ?, strides: [?, 1]>) 111 outs(%C : memref<?x?xf32, offset: ?, strides: [?, 1]>) { 112 ^bb(%a: f32, %b: f32, %c: f32): 113 %d = arith.mulf %a, %b: f32 114 %e = arith.addf %c, %d: f32 115 linalg.yield %e: f32 116 } 117 return 118} 119// CHECK-LABEL: func @permute_generic 120// CHECK: linalg.generic { 121// CHECK-SAME: indexing_maps = [#[[$kn]], #[[$nm]], #[[$km]]], 122// CHECK-SAME: iterator_types = ["parallel", "reduction", "parallel"], 123// CHECK-SAME: library_call = "linalg_matmul"} 124// CHECK: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, 125// CHECK-SAME: memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 126// CHECK-SAME: memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 127 128func @matvec_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 129 %x: memref<?xf32, offset: ?, strides: [1]>, 130 %y: memref<?xf32, offset: ?, strides: [1]>) { 131 linalg.matvec {__internal_linalg_transform__ = "__with_perm__"} 132 ins(%A, %x: memref<?x?xf32, offset: ?, strides: [?, 1]>, 133 memref<?xf32, offset: ?, strides: [1]>) 134 outs(%y: memref<?xf32, offset: ?, strides: [1]>) 135 return 136} 137// CHECK-LABEL: func @matvec_perm 138// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 139// CHECK-DAG: %[[c5:.*]] = arith.constant 5 : index 140// CHECK-DAG: %[[c6:.*]] = arith.constant 6 : index 141// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c6]] 142// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c5]] 143// CHECK: linalg.matvec 144// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?xf32, #[[$STRIDED_1D]]>) 145// CHECK: outs({{.*}}: memref<?xf32, #[[$STRIDED_1D]]>) 146 147func @matmul_perm(%A: memref<?x?xf32, offset: ?, strides: [?, 1]>, 148 %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 149 %C: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 150 linalg.matmul {__internal_linalg_transform__ = "__with_perm__"} 151 ins(%A, %B: memref<?x?xf32, offset: ?, strides: [?, 1]>, 152 memref<?x?xf32, offset: ?, strides: [?, 1]>) 153 outs(%C : memref<?x?xf32, offset: ?, strides: [?, 1]>) 154 return 155} 156// CHECK-LABEL: func @matmul_perm 157// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 158// CHECK-DAG: %[[c20:.*]] = arith.constant 20 : index 159// CHECK-DAG: %[[c30:.*]] = arith.constant 30 : index 160// CHECK-DAG: %[[c40:.*]] = arith.constant 40 : index 161// CHECK-DAG: %[[c200:.*]] = arith.constant 200 : index 162// CHECK-DAG: %[[c300:.*]] = arith.constant 300 : index 163// CHECK-DAG: %[[c400:.*]] = arith.constant 400 : index 164// CHECK-DAG: %[[c2000:.*]] = arith.constant 2000 : index 165// CHECK-DAG: %[[c3000:.*]] = arith.constant 3000 : index 166// CHECK-DAG: %[[c4000:.*]] = arith.constant 4000 : index 167// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 168// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 169// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 170// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c300]] { 171// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c200]] { 172// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c400]] { 173// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c20]] { 174// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c30]] { 175// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c40]] { 176// CHECK: linalg.matmul 177// CHECK: ins({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>, memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 178// CHECK: outs({{.*}}: memref<?x?xf32, #[[$STRIDED_2D_u_1]]>) 179 180func @promote_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>, 181 %arg1: memref<?x?xf32, offset: ?, strides: [?, 1]>, 182 %arg2: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 183 %c2000 = arith.constant 2000 : index 184 %c3000 = arith.constant 3000 : index 185 %c4000 = arith.constant 4000 : index 186 %c0 = arith.constant 0 : index 187 %c1 = arith.constant 1 : index 188 %0 = memref.dim %arg0, %c0 : memref<?x?xf32, offset: ?, strides: [?, 1]> 189 %1 = memref.dim %arg0, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 190 %2 = memref.dim %arg1, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 191 scf.for %arg3 = %c0 to %0 step %c2000 { 192 scf.for %arg4 = %c0 to %2 step %c3000 { 193 scf.for %arg5 = %c0 to %1 step %c4000 { 194 %3 = memref.subview %arg0[%arg3, %arg5][%c2000, %c4000][%c1, %c1] : 195 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 196 %4 = memref.subview %arg1[%arg5, %arg4][%c4000, %c3000][%c1, %c1] : 197 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 198 %5 = memref.subview %arg2[%arg3, %arg4][%c2000, %c3000][%c1, %c1] : 199 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 200 linalg.matmul {__internal_linalg_transform__ = "_promote_views_"} 201 ins(%3, %4: memref<?x?xf32, offset: ?, strides: [?, ?]>, 202 memref<?x?xf32, offset: ?, strides: [?, ?]>) 203 outs(%5: memref<?x?xf32, offset: ?, strides: [?, ?]>) 204 } 205 } 206 } 207 return 208} 209// CHECK-LABEL: func @promote_subview_matmul 210// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 211// CHECK-DAG: %[[c2000:.*]] = arith.constant 2000 : index 212// CHECK-DAG: %[[c3000:.*]] = arith.constant 3000 : index 213// CHECK-DAG: %[[c4000:.*]] = arith.constant 4000 : index 214// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 215// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 216// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 217// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 218// CHECK: %[[s1:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 219// CHECK: %[[s2:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 220// CHECK: %[[a0:.*]] = memref.alloc() : memref<32000000xi8> 221// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<32000000xi8> to memref<?x?xf32> 222// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] 223// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 224// CHECK: %[[a1:.*]] = memref.alloc() : memref<48000000xi8> 225// CHECK: %[[v1:.*]] = memref.view %[[a1]]{{.*}} : memref<48000000xi8> to memref<?x?xf32> 226// CHECK: %[[l1:.*]] = memref.subview %[[v1]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] 227// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 228// CHECK: %[[a2:.*]] = memref.alloc() : memref<24000000xi8> 229// CHECK: %[[v2:.*]] = memref.view %[[a2]]{{.*}} : memref<24000000xi8> to memref<?x?xf32> 230// CHECK: %[[l2:.*]] = memref.subview %[[v2]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] 231// CHECK-SAME: memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 232// CHECK: memref.copy %[[s0]], %[[l0]] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 233// CHECK: memref.copy %[[s1]], %[[l1]] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 234// CHECK: memref.copy %[[s2]], %[[l2]] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 235// CHECK: linalg.matmul 236// CHECK-SAME: ins(%[[v0]], %[[v1]] : memref<?x?xf32>, memref<?x?xf32>) 237// CHECK-SAME: outs(%[[v2]] : memref<?x?xf32>) 238 239func @promote_first_subview_matmul(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>, 240 %arg1: memref<?x?xf32, offset: ?, strides: [?, 1]>, 241 %arg2: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 242 %c2000 = arith.constant 2000 : index 243 %c3000 = arith.constant 3000 : index 244 %c4000 = arith.constant 4000 : index 245 %c0 = arith.constant 0 : index 246 %c1 = arith.constant 1 : index 247 %0 = memref.dim %arg0, %c0 : memref<?x?xf32, offset: ?, strides: [?, 1]> 248 %1 = memref.dim %arg0, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 249 %2 = memref.dim %arg1, %c1 : memref<?x?xf32, offset: ?, strides: [?, 1]> 250 scf.for %arg3 = %c0 to %0 step %c2000 { 251 scf.for %arg4 = %c0 to %2 step %c3000 { 252 scf.for %arg5 = %c0 to %1 step %c4000 { 253 %3 = memref.subview %arg0[%arg3, %arg5][%c2000, %c4000][%c1, %c1] : 254 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 255 %4 = memref.subview %arg1[%arg5, %arg4][%c4000, %c3000][%c1, %c1] : 256 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 257 %5 = memref.subview %arg2[%arg3, %arg4][%c2000, %c3000][%c1, %c1] : 258 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 259 linalg.matmul {__internal_linalg_transform__ = "_promote_first_view_"} 260 ins(%3, %4: memref<?x?xf32, offset: ?, strides: [?, ?]>, 261 memref<?x?xf32, offset: ?, strides: [?, ?]>) 262 outs(%5: memref<?x?xf32, offset: ?, strides: [?, ?]>) 263 } 264 } 265 } 266 return 267} 268// CHECK-LABEL: func @promote_first_subview_matmul 269// CHECK-DAG: %[[c0:.*]] = arith.constant 0 : index 270// CHECK-DAG: %[[c2000:.*]] = arith.constant 2000 : index 271// CHECK-DAG: %[[c3000:.*]] = arith.constant 3000 : index 272// CHECK-DAG: %[[c4000:.*]] = arith.constant 4000 : index 273// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c2000]] { 274// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c3000]] { 275// CHECK: scf.for {{.*}} = %[[c0]] to {{.*}} step %[[c4000]] { 276// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 277// CHECK: %[[s1:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 278// CHECK: %[[s2:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 279// CHECK: %[[a0:.*]] = memref.alloc() : memref<32000000xi8> 280// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<32000000xi8> to memref<?x?xf32> 281// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 282// CHECK-NOT: memref.alloc 283// CHECK-NOT: memref.view 284// CHECK-NOT: memref.subview 285// CHECK: memref.copy %[[s0]], %[[l0]] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 286// CHECK-NOT: memref.copy 287// CHECK: linalg.matmul 288// CHECK-SAME: ins(%[[v0]], %[[s1]] : memref<?x?xf32>, memref<?x?xf32, #[[$STRIDED_2D]]>) 289// CHECK-SAME: outs(%[[s2]] : memref<?x?xf32, #[[$STRIDED_2D]]>) 290 291func @aligned_promote_fill(%arg0: memref<?x?xf32, offset: ?, strides: [?, 1]>) { 292 %c2000 = arith.constant 2000 : index 293 %c4000 = arith.constant 4000 : index 294 %c0 = arith.constant 0 : index 295 %c1 = arith.constant 1 : index 296 %cf = arith.constant 1.0 : f32 297 %3 = memref.subview %arg0[%c0, %c0][%c2000, %c4000][%c1, %c1] : 298 memref<?x?xf32, offset: ?, strides: [?, 1]> to memref<?x?xf32, offset: ?, strides: [?, ?]> 299 linalg.fill { __internal_linalg_transform__ = "_promote_views_aligned_"} 300 ins(%cf : f32) outs(%3 : memref<?x?xf32, offset: ?, strides: [?, ?]>) 301 return 302} 303// CHECK-LABEL: func @aligned_promote_fill 304// CHECK: %[[cf:.*]] = arith.constant {{.*}} : f32 305// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 306// CHECK: %[[a0:.*]] = memref.alloc() {alignment = 32 : i64} : memref<32000000xi8> 307// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<32000000xi8> to memref<?x?xf32> 308// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xf32> to memref<?x?xf32, #[[$STRIDED_2D_u_1]]> 309// CHECK: linalg.fill ins({{.*}} : f32) outs(%[[v0]] : memref<?x?xf32>) 310// CHECK: memref.copy %[[s0]], %[[l0]] : memref<?x?xf32, #map{{.*}}> to memref<?x?xf32, #map{{.*}}> 311// CHECK: linalg.fill ins(%[[cf]] : f32) outs(%[[v0]] : memref<?x?xf32>) 312 313func @aligned_promote_fill_complex(%arg0: memref<?x?xcomplex<f32>, offset: ?, strides: [?, 1]>) { 314 %c2000 = arith.constant 2000 : index 315 %c4000 = arith.constant 4000 : index 316 %c0 = arith.constant 0 : index 317 %c1 = arith.constant 1 : index 318 %cf = arith.constant 1.0 : f32 319 %cc = complex.create %cf, %cf : complex<f32> 320 %3 = memref.subview %arg0[%c0, %c0][%c2000, %c4000][%c1, %c1] : 321 memref<?x?xcomplex<f32>, offset: ?, strides: [?, 1]> to memref<?x?xcomplex<f32>, offset: ?, strides: [?, ?]> 322 linalg.fill { __internal_linalg_transform__ = "_promote_views_aligned_"} 323 ins(%cc : complex<f32>) outs(%3 : memref<?x?xcomplex<f32>, offset: ?, strides: [?, ?]>) 324 return 325} 326// CHECK-LABEL: func @aligned_promote_fill_complex 327// CHECK: %[[cc:.*]] = complex.create {{.*}} : complex<f32> 328// CHECK: %[[s0:.*]] = memref.subview {{.*}}: memref<?x?xcomplex<f32>, #map{{.*}}> to memref<?x?xcomplex<f32>, #map{{.*}}> 329// CHECK: %[[a0:.*]] = memref.alloc() {alignment = 32 : i64} : memref<64000000xi8> 330// CHECK: %[[v0:.*]] = memref.view %[[a0]]{{.*}} : memref<64000000xi8> to memref<?x?xcomplex<f32>> 331// CHECK: %[[l0:.*]] = memref.subview %[[v0]][0, 0] [%{{.*}}, %{{.*}}] [1, 1] : memref<?x?xcomplex<f32>> to memref<?x?xcomplex<f32>, #[[$STRIDED_2D_u_1]]> 332// CHECK: linalg.fill ins({{.*}} : complex<f32>) outs(%[[v0]] : memref<?x?xcomplex<f32>>) 333// CHECK: memref.copy %[[s0]], %[[l0]] : memref<?x?xcomplex<f32>, #map{{.*}}> to memref<?x?xcomplex<f32>, #map{{.*}}> 334// CHECK: linalg.fill ins(%[[cc]] : complex<f32>) outs(%[[v0]] : memref<?x?xcomplex<f32>>) 335 336func @tile_permute_parallel_loop(%arg0: memref<?x?xf32>, 337 %arg1: memref<?x?xf32>, 338 %arg2: memref<?x?xf32>) { 339 linalg.matmul {__internal_linalg_transform__ = "par__with_perm__"} 340 ins(%arg0, %arg1: memref<?x?xf32>, memref<?x?xf32>) 341 outs(%arg2: memref<?x?xf32>) 342 return 343} 344// CHECK-LABEL: func @tile_permute_parallel_loop 345// CHECK-SAME: %[[ARG0:[a-zA-Z0-9_]+]]: memref<?x?xf32> 346// CHECK-SAME: %[[ARG1:[a-zA-Z0-9_]+]]: memref<?x?xf32> 347// CHECK-SAME: %[[ARG2:[a-zA-Z0-9_]+]]: memref<?x?xf32> 348// CHECK-DAG: %[[C16:.*]] = arith.constant 16 : index 349// CHECK-DAG: %[[C8:.*]] = arith.constant 8 : index 350// CHECK-DAG: %[[C4:.*]] = arith.constant 4 : index 351// CHECK-DAG: %[[C0:.*]] = arith.constant 0 : index 352// CHECK-DAG: %[[D0:.*]] = memref.dim %[[ARG0]], %c0 353// CHECK-DAG: %[[D1:.*]] = memref.dim %[[ARG0]], %c1 354// CHECK-DAG: %[[D2:.*]] = memref.dim %[[ARG1]], %c1 355// CHECK: scf.parallel (%{{.*}}) = (%[[C0]]) to (%[[D2]]) step (%[[C8]]) 356// CHECK: scf.for %{{.*}} = %[[C0]] to %[[D1]] step %[[C4]] 357// CHECK: scf.parallel (%{{.*}}) = (%[[C0]]) to (%[[D0]]) step (%[[C16]]) 358