blob: 910e5e5eb0c6fef2ccb11c4282e23b6d735a368b [file] [log] [blame]
// This file contains tests of linalg dialect operations with dynamic shapes.
#map = affine_map<(d0, d1, d2, d3) -> (d0, d1, d3)>
#map1 = affine_map<(d0, d1, d2, d3) -> (d0, d3, d2)>
#map2 = affine_map<(d0, d1, d2, d3) -> (d0, d1, d2)>
// Batched matmul where B=32 M=1 N=128 K=dynamic.
// Tested with K=3 and splat operands.
func.func @batch_matmul_dynamic_reduction_size_B32_M1_N128_K3() {
%lhs = flow.tensor.dynamic_constant dense<1.0> : tensor<32x1x3xf16> -> tensor<32x1x?xf16>
%rhs = flow.tensor.dynamic_constant dense<2.0> : tensor<32x3x128xf16> -> tensor<32x?x128xf16>
%cst = arith.constant 0.000000 : f16
%2 = tensor.empty() : tensor<32x1x128xf16>
%3 = linalg.fill ins(%cst : f16) outs(%2 : tensor<32x1x128xf16>) -> tensor<32x1x128xf16>
%observed = linalg.generic {
indexing_maps = [#map, #map1, #map2],
iterator_types = ["parallel", "parallel", "parallel", "reduction"]}
ins(%lhs, %rhs : tensor<32x1x?xf16>, tensor<32x?x128xf16>) outs(%3 : tensor<32x1x128xf16>) {
^bb0(%in: f16, %in_0: f16, %out: f16):
%6 = arith.mulf %in, %in_0 : f16
%7 = arith.addf %out, %6 : f16
linalg.yield %7 : f16
} -> tensor<32x1x128xf16>
%expected = flow.tensor.dynamic_constant dense<6.0> : tensor<32x1x128xf16> -> tensor<32x1x128xf16>
check.expect_almost_eq(%observed, %expected, atol 1.0e-04) : tensor<32x1x128xf16>
return
}
// Batched matmul where B=2 M=1 N=3 K=dynamic.
// Tested with K=5 and operands with varying values.
func.func @dynamic_matmul_dynamic_reduction_size_B2_M1_N3_K5() {
%lhs = flow.tensor.dynamic_constant dense<[[[1.0, 2.0, 3.0, 4.0, 5.0]],
[[6.0, 7.0, 8.0, 9.0, 10.0]]]>
: tensor<2x1x5xf16> -> tensor<2x1x?xf16>
%rhs = flow.tensor.dynamic_constant dense<[[[11.0, 12.0, 13.0],
[14.0, 15.0, 16.0],
[17.0, 18.0, 19.0],
[20.0, 21.0, 22.0],
[23.0, 24.0, 25.0]],
[[26.0, 27.0, 28.0],
[29.0, 30.0, 31.0],
[32.0, 33.0, 34.0],
[35.0, 36.0, 37.0],
[38.0, 39.0, 40.0]]]>
: tensor<2x5x3xf16> -> tensor<2x?x3xf16>
%cst = arith.constant 0.000000 : f16
%2 = tensor.empty() : tensor<2x1x3xf16>
%3 = linalg.fill ins(%cst : f16) outs(%2 : tensor<2x1x3xf16>) -> tensor<2x1x3xf16>
%observed = linalg.generic {
indexing_maps = [#map, #map1, #map2],
iterator_types = ["parallel", "parallel", "parallel", "reduction"]}
ins(%lhs, %rhs : tensor<2x1x?xf16>, tensor<2x?x3xf16>) outs(%3 : tensor<2x1x3xf16>) {
^bb0(%in: f16, %in_0: f16, %out: f16):
%6 = arith.mulf %in, %in_0 : f16
%7 = arith.addf %out, %6 : f16
linalg.yield %7 : f16
} -> tensor<2x1x3xf16>
%expected = flow.tensor.dynamic_constant dense<[
[[285.0, 300.0, 315.0]],
[[1310.0, 1350.0, 1390.0]]
]> : tensor<2x1x3xf16> -> tensor<2x1x3xf16>
check.expect_almost_eq(%observed, %expected, atol 1.0e-04) : tensor<2x1x3xf16>
return
}
// Softmax operation with dynamic reduction size.
// Number of samples: 2. Size of reduction dimension: 4.
func.func @softmax_dynamic_reduction_N2_K4(){
// Computed with numpy, values of ln([[3, 2, 4, 1.],[1, 7, 1, 1]]).
%input = flow.tensor.dynamic_constant dense<
[[1.09861229, 0.69314718, 1.38629436, 0. ],
[0. , 1.94591015, 0. , 0. ]]> : tensor<2x4xf32> -> tensor<2x?xf32>
%expected = flow.tensor.dynamic_constant dense<
[[0.3, 0.2, 0.4, 0.1],
[0.1, 0.7, 0.1, 0.1]]> : tensor<2x4xf32> -> tensor<2x?xf32>
%c_1_index = arith.constant 1 : index
%dim_0 = tensor.dim %input, %c_1_index : tensor<2x?xf32>
%output = tensor.empty(%dim_0) : tensor<2x?xf32>
%sm = linalg.softmax dimension(1) ins(%input : tensor<2x?xf32>)
outs(%output : tensor<2x?xf32>) -> tensor<2x?xf32>
check.expect_almost_eq(%sm, %expected, atol 1.0e-04) : tensor<2x?xf32>
return
}
// Softmax operation with dynamic reduction size.
// Number of samples: 1. Size of reduction dimension: 1.
func.func @softmax_dynamic_reduction_N1_K1(){
%input = flow.tensor.dynamic_constant dense<[[-77.7]]> : tensor<1x1xf32> -> tensor<1x?xf32>
%expected = flow.tensor.dynamic_constant dense<[[1.0]]> : tensor<1x1xf32> -> tensor<1x?xf32>
%c_1_index = arith.constant 1 : index
%dim_0 = tensor.dim %input, %c_1_index : tensor<1x?xf32>
%output = tensor.empty(%dim_0) : tensor<1x?xf32>
%sm = linalg.softmax dimension(1) ins(%input : tensor<1x?xf32>)
outs(%output : tensor<1x?xf32>) -> tensor<1x?xf32>
check.expect_almost_eq(%sm, %expected, atol 1.0e-04) : tensor<1x?xf32>
return
}
// Softmax operation with dynamic reduction size.
// Number of samples: 65. Size of reduction dimension: 1531.
func.func @softmax_dynamic_reduction_N65_K1531(){
%input = flow.tensor.dynamic_constant dense<-3.1415> :
tensor<65x1531xf32> -> tensor<65x?xf32>
// 1/1531 is 0.0006531678641410843
%expected = flow.tensor.dynamic_constant dense<0.0006531678641410843> :
tensor<65x1531xf32> -> tensor<65x?xf32>
%c_1_index = arith.constant 1 : index
%dim_0 = tensor.dim %input, %c_1_index : tensor<65x?xf32>
%output = tensor.empty(%dim_0) : tensor<65x?xf32>
%sm = linalg.softmax dimension(1) ins(%input : tensor<65x?xf32>)
outs(%output : tensor<65x?xf32>) -> tensor<65x?xf32>
check.expect_almost_eq(%sm, %expected, atol 1.0e-04) : tensor<65x?xf32>
return
}