blob: f639092be19eda60f1ee40160146ea40c6de7056 [file] [log] [blame]
// RUN: iree-opt -split-input-file -iree-codegen-hlo-to-linalg-on-buffers %s | IreeFileCheck %s
// CHECK: #[[MAP0:.+]] = affine_map<(d0, d1) -> (d0, d1)>
// CHECK: #[[MAP1:.+]] = affine_map<(d0, d1) -> ()>
// CHECK: #[[MAP2:.+]] = affine_map<(d0, d1) -> (d0)>
module {
// CHECK: func @reduction_entry
// CHECK-DAG: %[[ARG2:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@ret0} : memref<5xf32>
// CHECK-DAG: %[[ARG0:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@arg0} : memref<5x4xf32>
// CHECK-DAG: %[[ARG1:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@arg1} : memref<f32>
// CHECK: linalg.indexed_generic {args_in = 2 : i64, args_out = 1 : i64,
// CHECK-SAME: indexing_maps
// CHECK-SAME: #[[MAP0]], #[[MAP1]], #[[MAP2]]
// CHECK-SAME: iterator_types = ["parallel", "reduction"]}
// CHECK-SAME: %[[ARG0]], %[[ARG1]], %[[ARG2]] {
// CHECK-NEXT: ^{{.+}}(%{{.+}}, %[[IDX:.+]]: index, %[[SRC:.+]]: f32, %[[INIT:.+]]: f32, %[[DST:.+]]: f32):
// CHECK: %[[OPERAND:.+]] = select %{{.+}}, %[[INIT]], %[[DST]] : f32
// CHECK-NEXT: %[[RES:.+]] = addf %[[SRC]], %[[OPERAND]] : f32
// CHECK-NEXT: linalg.yield %[[RES]] : f32
// CHECK-NEXT: }: memref<5x4xf32>, memref<f32>, memref<5xf32>
func @reduction_entry() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<5x4xf32>
%1 = hal.interface.load.tensor @legacy_io::@arg1, offset = %c0 : tensor<f32>
%2 = "mhlo.reduce"(%0, %1) ({
^bb0(%arg3: tensor<f32>, %arg4 : tensor<f32>):
%3 = mhlo.add %arg3, %arg4 : tensor<f32>
"mhlo.return"(%3) : (tensor<f32>) -> ()
}) {dimensions = dense<1> : tensor<1xi64>} : (tensor<5x4xf32>, tensor<f32>) -> tensor<5xf32>
hal.interface.store.tensor %2, @legacy_io::@ret0, offset = %c0 : tensor<5xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}
// -----
module {
// CHECK: %[[COND:.+]] = cmpf "olt", %{{.+}}, %{{.+}} : f32
// CHECK-NEXT: select %[[COND]], %{{.+}}, %{{.+}} : f32
func @reduction_entry() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<5x4xf32>
%1 = hal.interface.load.tensor @legacy_io::@arg1, offset = %c0 : tensor<f32>
%2 = "mhlo.reduce"(%0, %1) ({
^bb0(%arg3: tensor<f32>, %arg4 : tensor<f32>):
%3 = mhlo.minimum %arg3, %arg4 : tensor<f32>
"mhlo.return"(%3) : (tensor<f32>) -> ()
}) {dimensions = dense<1> : tensor<1xi64>} : (tensor<5x4xf32>, tensor<f32>) -> tensor<5xf32>
hal.interface.store.tensor %2, @legacy_io::@ret0, offset = %c0 : tensor<5xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}
// -----
module {
// CHECK: %[[COND:.+]] = cmpf "ogt", %{{.+}}, %{{.+}} : f32
// CHECK-NEXT: select %[[COND]], %{{.+}}, %{{.+}} : f32
func @reduction_entry() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<5x4xf32>
%1 = hal.interface.load.tensor @legacy_io::@arg1, offset = %c0 : tensor<f32>
%2 = "mhlo.reduce"(%0, %1) ({
^bb0(%arg3: tensor<f32>, %arg4 : tensor<f32>):
%3 = mhlo.maximum %arg3, %arg4 : tensor<f32>
"mhlo.return"(%3) : (tensor<f32>) -> ()
}) {dimensions = dense<1> : tensor<1xi64>} : (tensor<5x4xf32>, tensor<f32>) -> tensor<5xf32>
hal.interface.store.tensor %2, @legacy_io::@ret0, offset = %c0 : tensor<5xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}
// -----
module {
// CHECK: %[[COND:.+]] = cmpf "ogt", %{{.+}}, %{{.+}} : f32
// CHECK-NEXT: select %[[COND]], %{{.+}}, %{{.+}} : f32
func @reduction_entry() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<5x4xf32>
%1 = hal.interface.load.tensor @legacy_io::@arg1, offset = %c0 : tensor<f32>
%2 = "mhlo.reduce"(%0, %1) ({
^bb0(%arg3: tensor<f32>, %arg4 : tensor<f32>):
%3 = mhlo.maximum %arg3, %arg4 : tensor<f32>
"mhlo.return"(%3) : (tensor<f32>) -> ()
}) {dimensions = dense<0> : tensor<1xi64>} : (tensor<5x4xf32>, tensor<f32>) -> tensor<4xf32>
hal.interface.store.tensor %2, @legacy_io::@ret0, offset = %c0 : tensor<4xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}
// -----
// CHECK: #[[MAP0:.+]] = affine_map<(d0, d1) -> (d1, d0)>
// CHECK: #[[MAP1:.+]] = affine_map<(d0, d1) -> ()>
// CHECK: #[[MAP2:.+]] = affine_map<(d0, d1) -> (d0)>
module {
// CHECK: func @reduction_entry
// CHECK: %[[ARG2:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@ret0} : memref<4xf32>
// CHECK: %[[ARG0:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@arg0} : memref<5x4xf32>
// CHECK: %[[ARG1:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@arg1} : memref<f32>
// CHECK: linalg.indexed_generic {args_in = 2 : i64, args_out = 1 : i64,
// CHECK-SAME: indexing_maps
// CHECK-SAME: #[[MAP0]], #[[MAP1]], #[[MAP2]]
// CHECK-SAME: iterator_types = ["parallel", "reduction"]}
// CHECK-SAME: %[[ARG0]], %[[ARG1]], %[[ARG2]] {
// CHECK-NEXT: ^{{.+}}(%{{.+}}, %[[IDX:.+]]: index, %[[SRC:.+]]: f32, %[[INIT:.+]]: f32, %[[DST:.+]]: f32):
// CHECK: %[[OPERAND:.+]] = select %{{.+}}, %[[INIT]], %[[DST]] : f32
// CHECK-NEXT: %[[RES:.+]] = addf %[[SRC]], %[[OPERAND]] : f32
// CHECK-NEXT: linalg.yield %[[RES]] : f32
// CHECK-NEXT: }: memref<5x4xf32>, memref<f32>, memref<4xf32>
func @reduction_entry() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<5x4xf32>
%1 = hal.interface.load.tensor @legacy_io::@arg1, offset = %c0 : tensor<f32>
%2 = "mhlo.reduce"(%0, %1) ({
^bb0(%arg3: tensor<f32>, %arg4 : tensor<f32>):
%3 = mhlo.add %arg3, %arg4 : tensor<f32>
"mhlo.return"(%3) : (tensor<f32>) -> ()
}) {dimensions = dense<0> : tensor<1xi64>} : (tensor<5x4xf32>, tensor<f32>) -> tensor<4xf32>
hal.interface.store.tensor %2, @legacy_io::@ret0, offset = %c0 : tensor<4xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}
// -----
module {
// CHECK-LABEL: func @reduce_init_const
func @reduce_init_const() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<1x10xf32>
// CHECK: %[[CST:.+]] = constant 0xFF800000 : f32
// CHECK: linalg.indexed_generic
// CHECK-SAME: args_in = 1
// CHECK-SAME: args_out = 1
// CHECK: ^{{.+}}(%{{.+}}: index, %[[DIM:.+]]: index, %{{.+}}: f32, %[[OUTPUT:.+]]: f32):
// CHECK: select %{{.+}}, %[[CST]], %[[OUTPUT]] : f32
%cst = constant dense<0xFF800000> : tensor<f32>
%1 = "mhlo.reduce"(%0, %cst) ({
^bb0(%arg2: tensor<f32>, %arg3: tensor<f32>): // no predecessors
%2 = mhlo.add %arg2, %arg3 {name = "maximum.21"} : tensor<f32>
"mhlo.return"(%2) : (tensor<f32>) -> ()
}) {dimensions = dense<1> : tensor<1xi64>} : (tensor<1x10xf32>, tensor<f32>) -> tensor<1xf32>
hal.interface.store.tensor %1, @legacy_io::@ret0, offset = %c0 : tensor<1xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=1, type="StorageBuffer", access="Write"
}
}
// -----
// CHECK: #[[MAP0:.+]] = affine_map<(d0, d1, d2) -> (d1, d0, d2)>
// CHECK: #[[MAP1:.+]] = affine_map<(d0, d1, d2) -> ()>
// CHECK: #[[MAP2:.+]] = affine_map<(d0, d1, d2) -> (d0)>
module {
// CHECK: func @reduction_multi_dimensions
// CHECK: %[[ARG2:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@ret0} : memref<4xf32>
// CHECK: %[[ARG0:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@arg0} : memref<5x4x3xf32>
// CHECK: %[[ARG1:.+]] = iree.placeholder for "interface buffer" {binding = @legacy_io::@arg1} : memref<f32>
// CHECK: linalg.indexed_generic {args_in = 2 : i64, args_out = 1 : i64,
// CHECK-SAME: indexing_maps
// CHECK-SAME: #[[MAP0]], #[[MAP1]], #[[MAP2]]
// CHECK-SAME: iterator_types = ["parallel", "reduction", "reduction"]}
// CHECK-SAME: %[[ARG0]], %[[ARG1]], %[[ARG2]] {
// CHECK-NEXT: ^{{.+}}(%{{.+}}, %[[IDX:.+]]: index, %[[SRC:.+]]: f32, %[[INIT:.+]]: f32, %[[DST:.+]]: f32):
// CHECK: %[[TRUE:.+]] = constant true
// CHECK: %[[CMP1:.+]] = cmpi
// CHECK: %[[COND1:.+]] = and %[[TRUE]], %[[CMP1]]
// CHECK: %[[CMP2:.+]] = cmpi
// CHECK: %[[COND2:.+]] = and %[[COND1]], %[[CMP2]]
// CHECK-NEXT: %[[OPERAND:.+]] = select %[[COND2]], %[[INIT]], %[[DST]] : f32
// CHECK-NEXT: %[[RES:.+]] = addf %[[SRC]], %[[OPERAND]] : f32
// CHECK-NEXT: linalg.yield %[[RES]] : f32
// CHECK-NEXT: }: memref<5x4x3xf32>, memref<f32>, memref<4xf32>
func @reduction_multi_dimensions() {
%c0 = constant 0 : index
%0 = hal.interface.load.tensor @legacy_io::@arg0, offset = %c0 : tensor<5x4x3xf32>
%1 = hal.interface.load.tensor @legacy_io::@arg1, offset = %c0 : tensor<f32>
%2 = "mhlo.reduce"(%0, %1) ({
^bb0(%arg3: tensor<f32>, %arg4 : tensor<f32>):
%3 = mhlo.add %arg3, %arg4 : tensor<f32>
"mhlo.return"(%3) : (tensor<f32>) -> ()
}) {dimensions = dense<[0, 2]> : tensor<2xi64>} : (tensor<5x4x3xf32>, tensor<f32>) -> tensor<4xf32>
hal.interface.store.tensor %2, @legacy_io::@ret0, offset = %c0 : tensor<4xf32>
return
}
hal.interface @legacy_io attributes {sym_visibility = "private"} {
hal.interface.binding @arg0, set=0, binding=0, type="StorageBuffer", access="Read"
hal.interface.binding @arg1, set=0, binding=1, type="StorageBuffer", access="Read"
hal.interface.binding @ret0, set=0, binding=2, type="StorageBuffer", access="Write"
}
}