|
1 | 1 | // RUN: mlir-proto-opt %s \ |
2 | 2 | // RUN: -convert-iterators-to-llvm \ |
3 | 3 | // RUN: -convert-states-to-llvm \ |
4 | | -// RUN: -convert-func-to-llvm \ |
5 | | -// RUN: -convert-scf-to-cf -convert-cf-to-llvm \ |
| 4 | +// RUN: -convert-scf-to-cf \ |
| 5 | +// RUN: -arith-bufferize -func-bufferize -tensor-bufferize \ |
| 6 | +// RUN: -convert-func-to-llvm -convert-memref-to-llvm \ |
| 7 | +// RUN: -cse -reconcile-unrealized-casts \ |
6 | 8 | // RUN: | mlir-cpu-runner -e main -entry-point-result=void \ |
7 | 9 | // RUN: | FileCheck %s |
8 | 10 |
|
9 | 11 | !struct_i32 = !llvm.struct<(i32)> |
10 | 12 | !struct_i32i32 = !llvm.struct<(i32, i32)> |
| 13 | +!struct_i32i32i32i32 = !llvm.struct<(i32, i32, i32, i32)> |
11 | 14 | !struct_f32 = !llvm.struct<(f32)> |
12 | 15 |
|
13 | 16 | func.func private @init_sum_struct() -> !struct_i32 { |
@@ -84,8 +87,62 @@ func.func @test_accumulate_avg_struct() { |
84 | 87 | return |
85 | 88 | } |
86 | 89 |
|
| 90 | +func.func private @unpack_i32(%input : !struct_i32) -> i32 { |
| 91 | + %i = llvm.extractvalue %input[0 : index] : !struct_i32 |
| 92 | + return %i : i32 |
| 93 | +} |
| 94 | + |
| 95 | +func.func private @init_histogram() -> tensor<4xi32> { |
| 96 | + %init = arith.constant dense<[0, 0, 0, 0]> : tensor<4xi32> |
| 97 | + return %init : tensor<4xi32> |
| 98 | +} |
| 99 | + |
| 100 | +func.func private @accumulate_histogram( |
| 101 | + %hist : tensor<4xi32>, %val : i32) -> tensor<4xi32> { |
| 102 | + %idx = arith.index_cast %val : i32 to index |
| 103 | + %oldCount = tensor.extract %hist[%idx] : tensor<4xi32> |
| 104 | + %one = arith.constant 1 : i32 |
| 105 | + %newCount = arith.addi %oldCount, %one : i32 |
| 106 | + %newHist = tensor.insert %newCount into %hist[%idx] : tensor<4xi32> |
| 107 | + return %newHist : tensor<4xi32> |
| 108 | +} |
| 109 | + |
| 110 | +func.func private @tensor_to_struct(%input : tensor<4xi32>) -> !struct_i32i32i32i32 { |
| 111 | + %idx0 = arith.constant 0 : index |
| 112 | + %idx1 = arith.constant 1 : index |
| 113 | + %idx2 = arith.constant 2 : index |
| 114 | + %idx3 = arith.constant 3 : index |
| 115 | + %i0 = tensor.extract %input[%idx0] : tensor<4xi32> |
| 116 | + %i1 = tensor.extract %input[%idx1] : tensor<4xi32> |
| 117 | + %i2 = tensor.extract %input[%idx2] : tensor<4xi32> |
| 118 | + %i3 = tensor.extract %input[%idx3] : tensor<4xi32> |
| 119 | + %structu = llvm.mlir.undef : !struct_i32i32i32i32 |
| 120 | + %struct0 = llvm.insertvalue %i0, %structu[0 : index] : !struct_i32i32i32i32 |
| 121 | + %struct1 = llvm.insertvalue %i1, %struct0[1 : index] : !struct_i32i32i32i32 |
| 122 | + %struct2 = llvm.insertvalue %i2, %struct1[2 : index] : !struct_i32i32i32i32 |
| 123 | + %struct3 = llvm.insertvalue %i3, %struct2[3 : index] : !struct_i32i32i32i32 |
| 124 | + return %struct3 : !struct_i32i32i32i32 |
| 125 | +} |
| 126 | + |
| 127 | +func.func @test_accumulate_histogram() { |
| 128 | + %input = "iterators.constantstream"() |
| 129 | + { value = [[0 : i32], [1 : i32], [1 : i32], [2 : i32]] } |
| 130 | + : () -> (!iterators.stream<!struct_i32>) |
| 131 | + %unpacked = "iterators.map"(%input) {mapFuncRef = @unpack_i32} |
| 132 | + : (!iterators.stream<!struct_i32>) -> (!iterators.stream<i32>) |
| 133 | + %accumulated = iterators.accumulate(%unpacked, @init_histogram, |
| 134 | + @accumulate_histogram) |
| 135 | + : (!iterators.stream<i32>) -> !iterators.stream<tensor<4xi32>> |
| 136 | + %transposed = "iterators.map"(%accumulated) {mapFuncRef = @tensor_to_struct} |
| 137 | + : (!iterators.stream<tensor<4xi32>>) -> (!iterators.stream<!struct_i32i32i32i32>) |
| 138 | + "iterators.sink"(%transposed) : (!iterators.stream<!struct_i32i32i32i32>) -> () |
| 139 | + // CHECK: (1, 2, 1, 0) |
| 140 | + return |
| 141 | +} |
| 142 | + |
87 | 143 | func.func @main() { |
88 | 144 | call @test_accumulate_sum_struct() : () -> () |
89 | 145 | call @test_accumulate_avg_struct() : () -> () |
| 146 | + call @test_accumulate_histogram() : () -> () |
90 | 147 | return |
91 | 148 | } |
0 commit comments