Kina.ai

Example

ad_nll.kina

Source
let nll = fn(logits: tensor<F32, [1, 4, 8], @host>) -> tensor<F32, [1, 4], @host> {
  let targets = tensor<I64, [1, 4], @host> in
  let log_probs = logits.log_softmax(axis=2) in
  let picked = log_probs.take_along_axis(targets, axis=2) in
  let loss = -picked in
  loss
} in
let logits = tensor<F32, [1, 4, 8], @host> in
handle nll(logits) with reverseMode
Emitted MLIR (golden)
module {
  func.func @fn_val_0(%1: tensor<1x32x64xf32>, %2: tensor<1x1x64xf32>) -> tensor<1x32x64xf32> attributes {llvm.emit_c_interface} {
      %3 = tensor.empty() : tensor<1x32x64xf32>
      %4 = linalg.mul ins(%1, %1 : tensor<1x32x64xf32>, tensor<1x32x64xf32>) outs(%3 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %7 = arith.constant 0.000000e+00 : f32
      %5 = tensor.empty() : tensor<1x32x1xf32>
      %6 = linalg.fill ins(%7 : f32) outs(%5 : tensor<1x32x1xf32>) -> tensor<1x32x1xf32>
      %8 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%4 : tensor<1x32x64xf32>) outs(%6 : tensor<1x32x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %9 = arith.addf %a0, %a1 : f32
        linalg.yield %9 : f32
      } -> tensor<1x32x1xf32>
      %10 = arith.constant dense<0.000000e+00> : tensor<1x1x1xf32>
      %11 = tensor.empty() : tensor<1x32x1xf32>
      %12 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, 0, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%10 : tensor<1x1x1xf32>) outs(%11 : tensor<1x32x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x1xf32>
      %13 = tensor.empty() : tensor<1x32x1xf32>
      %14 = linalg.mul ins(%8, %12 : tensor<1x32x1xf32>, tensor<1x32x1xf32>) outs(%13 : tensor<1x32x1xf32>) -> tensor<1x32x1xf32>
      %15 = arith.constant dense<0.000000e+00> : tensor<1x1x1xf32>
      %16 = tensor.empty() : tensor<1x32x1xf32>
      %17 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, 0, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%15 : tensor<1x1x1xf32>) outs(%16 : tensor<1x32x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x1xf32>
      %18 = tensor.empty() : tensor<1x32x1xf32>
      %19 = linalg.add ins(%14, %17 : tensor<1x32x1xf32>, tensor<1x32x1xf32>) outs(%18 : tensor<1x32x1xf32>) -> tensor<1x32x1xf32>
      %23 = tensor.empty() : tensor<1x32x1xf32>
      %24 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%19 : tensor<1x32x1xf32>) outs(%23 : tensor<1x32x1xf32>) {
      ^bb0(%x: f32, %_: f32):
        %20 = math.sqrt %x : f32
        %21 = arith.constant 1.000000e+00 : f32
        %22 = arith.divf %21, %20 : f32
        linalg.yield %22 : f32
      } -> tensor<1x32x1xf32>
      %25 = tensor.empty() : tensor<1x32x64xf32>
      %26 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%24 : tensor<1x32x1xf32>) outs(%25 : tensor<1x32x64xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x64xf32>
      %27 = tensor.empty() : tensor<1x32x64xf32>
      %28 = linalg.mul ins(%1, %26 : tensor<1x32x64xf32>, tensor<1x32x64xf32>) outs(%27 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %29 = tensor.empty() : tensor<1x32x64xf32>
      %30 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, 0, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%2 : tensor<1x1x64xf32>) outs(%29 : tensor<1x32x64xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x64xf32>
      %31 = tensor.empty() : tensor<1x32x64xf32>
      %32 = linalg.mul ins(%28, %30 : tensor<1x32x64xf32>, tensor<1x32x64xf32>) outs(%31 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
    return %32 : tensor<1x32x64xf32>
  }
  func.func @fn_val_33(%34: tensor<1x32x64xf32>, %35: tensor<1x64x128xf32>, %36: tensor<1x128x64xf32>) -> tensor<1x32x64xf32> attributes {llvm.emit_c_interface} {
      %37 = arith.constant dense<0.000000e+00> : tensor<1x32x128xf32>
      %38 = linalg.batch_matmul ins(%34, %35 : tensor<1x32x64xf32>, tensor<1x64x128xf32>) outs(%37 : tensor<1x32x128xf32>) -> tensor<1x32x128xf32>
      %44 = tensor.empty() : tensor<1x32x128xf32>
      %45 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%38 : tensor<1x32x128xf32>) outs(%44 : tensor<1x32x128xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %39 = arith.constant 1.000000e+00 : f32
        %40 = arith.negf %a0 : f32
        %41 = math.exp %40 : f32
        %42 = arith.addf %39, %41 : f32
        %43 = arith.divf %39, %42 : f32
        linalg.yield %43 : f32
      } -> tensor<1x32x128xf32>
      %46 = tensor.empty() : tensor<1x32x128xf32>
      %47 = linalg.mul ins(%38, %45 : tensor<1x32x128xf32>, tensor<1x32x128xf32>) outs(%46 : tensor<1x32x128xf32>) -> tensor<1x32x128xf32>
      %48 = arith.constant dense<0.000000e+00> : tensor<1x32x64xf32>
      %49 = linalg.batch_matmul ins(%47, %36 : tensor<1x32x128xf32>, tensor<1x128x64xf32>) outs(%48 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
    return %49 : tensor<1x32x64xf32>
  }
  func.func @fn_val_50(%51: tensor<1x32x64xf32>, %52: tensor<1x64x64xf32>, %53: tensor<1x64x64xf32>, %54: tensor<1x64x64xf32>, %55: tensor<1x64x64xf32>) -> tensor<1x32x64xf32> attributes {llvm.emit_c_interface} {
      %56 = arith.constant dense<0.000000e+00> : tensor<1x32x64xf32>
      %57 = linalg.batch_matmul ins(%51, %52 : tensor<1x32x64xf32>, tensor<1x64x64xf32>) outs(%56 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %58 = arith.constant dense<0.000000e+00> : tensor<1x32x64xf32>
      %59 = linalg.batch_matmul ins(%51, %53 : tensor<1x32x64xf32>, tensor<1x64x64xf32>) outs(%58 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %60 = arith.constant dense<0.000000e+00> : tensor<1x32x64xf32>
      %61 = linalg.batch_matmul ins(%51, %54 : tensor<1x32x64xf32>, tensor<1x64x64xf32>) outs(%60 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %62 = tensor.empty() : tensor<1x64x32xf32>
      %63 = linalg.transpose ins(%59 : tensor<1x32x64xf32>) outs(%62 : tensor<1x64x32xf32>) permutation = [0, 2, 1]
      %64 = arith.constant dense<0.000000e+00> : tensor<1x32x32xf32>
      %65 = linalg.batch_matmul ins(%57, %63 : tensor<1x32x64xf32>, tensor<1x64x32xf32>) outs(%64 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %66 = arith.constant dense<0.000000e+00> : tensor<1x1x1xf32>
      %67 = tensor.empty() : tensor<1x32x32xf32>
      %68 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, 0, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%66 : tensor<1x1x1xf32>) outs(%67 : tensor<1x32x32xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x32xf32>
      %69 = tensor.empty() : tensor<1x32x32xf32>
      %70 = linalg.mul ins(%65, %68 : tensor<1x32x32xf32>, tensor<1x32x32xf32>) outs(%69 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %73 = arith.constant 0xFF800000 : f32
      %71 = tensor.empty() : tensor<1x32x1xf32>
      %72 = linalg.fill ins(%73 : f32) outs(%71 : tensor<1x32x1xf32>) -> tensor<1x32x1xf32>
      %74 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%70 : tensor<1x32x32xf32>) outs(%72 : tensor<1x32x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %75 = arith.maximumf %a0, %a1 : f32
        linalg.yield %75 : f32
      } -> tensor<1x32x1xf32>
      %76 = tensor.empty() : tensor<1x32x32xf32>
      %77 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%74 : tensor<1x32x1xf32>) outs(%76 : tensor<1x32x32xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x32xf32>
      %78 = tensor.empty() : tensor<1x32x32xf32>
      %79 = linalg.sub ins(%70, %77 : tensor<1x32x32xf32>, tensor<1x32x32xf32>) outs(%78 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %80 = tensor.empty() : tensor<1x32x32xf32>
      %81 = linalg.exp ins(%79 : tensor<1x32x32xf32>) outs(%80 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %84 = arith.constant 0xFF800000 : f32
      %82 = tensor.empty() : tensor<1x32x1xf32>
      %83 = linalg.fill ins(%84 : f32) outs(%82 : tensor<1x32x1xf32>) -> tensor<1x32x1xf32>
      %85 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%70 : tensor<1x32x32xf32>) outs(%83 : tensor<1x32x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %86 = arith.maximumf %a0, %a1 : f32
        linalg.yield %86 : f32
      } -> tensor<1x32x1xf32>
      %87 = tensor.empty() : tensor<1x32x32xf32>
      %88 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%85 : tensor<1x32x1xf32>) outs(%87 : tensor<1x32x32xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x32xf32>
      %89 = tensor.empty() : tensor<1x32x32xf32>
      %90 = linalg.sub ins(%70, %88 : tensor<1x32x32xf32>, tensor<1x32x32xf32>) outs(%89 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %91 = tensor.empty() : tensor<1x32x32xf32>
      %92 = linalg.exp ins(%90 : tensor<1x32x32xf32>) outs(%91 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %95 = arith.constant 0.000000e+00 : f32
      %93 = tensor.empty() : tensor<1x32x1xf32>
      %94 = linalg.fill ins(%95 : f32) outs(%93 : tensor<1x32x1xf32>) -> tensor<1x32x1xf32>
      %96 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%92 : tensor<1x32x32xf32>) outs(%94 : tensor<1x32x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %97 = arith.addf %a0, %a1 : f32
        linalg.yield %97 : f32
      } -> tensor<1x32x1xf32>
      %98 = tensor.empty() : tensor<1x32x32xf32>
      %99 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%96 : tensor<1x32x1xf32>) outs(%98 : tensor<1x32x32xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x32x32xf32>
      %100 = tensor.empty() : tensor<1x32x32xf32>
      %101 = linalg.div ins(%81, %99 : tensor<1x32x32xf32>, tensor<1x32x32xf32>) outs(%100 : tensor<1x32x32xf32>) -> tensor<1x32x32xf32>
      %102 = arith.constant dense<0.000000e+00> : tensor<1x32x64xf32>
      %103 = linalg.batch_matmul ins(%101, %61 : tensor<1x32x32xf32>, tensor<1x32x64xf32>) outs(%102 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %104 = arith.constant dense<0.000000e+00> : tensor<1x32x64xf32>
      %105 = linalg.batch_matmul ins(%103, %55 : tensor<1x32x64xf32>, tensor<1x64x64xf32>) outs(%104 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
    return %105 : tensor<1x32x64xf32>
  }
  func.func @fn_val_106(%107: tensor<1x32x64xf32>, %108: tensor<1x1x64xf32>, %109: tensor<1x64x64xf32>, %110: tensor<1x64x64xf32>, %111: tensor<1x64x64xf32>, %112: tensor<1x64x64xf32>, %113: tensor<1x1x64xf32>, %114: tensor<1x64x128xf32>, %115: tensor<1x128x64xf32>) -> tensor<1x32x64xf32> attributes {llvm.emit_c_interface} {
      %116 = func.call @fn_val_0(%107, %108) : (tensor<1x32x64xf32>, tensor<1x1x64xf32>) -> tensor<1x32x64xf32>
      %117 = func.call @fn_val_50(%116, %109, %110, %111, %112) : (tensor<1x32x64xf32>, tensor<1x64x64xf32>, tensor<1x64x64xf32>, tensor<1x64x64xf32>, tensor<1x64x64xf32>) -> tensor<1x32x64xf32>
      %118 = tensor.empty() : tensor<1x32x64xf32>
      %119 = linalg.add ins(%107, %117 : tensor<1x32x64xf32>, tensor<1x32x64xf32>) outs(%118 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
      %120 = func.call @fn_val_0(%119, %113) : (tensor<1x32x64xf32>, tensor<1x1x64xf32>) -> tensor<1x32x64xf32>
      %121 = func.call @fn_val_33(%120, %114, %115) : (tensor<1x32x64xf32>, tensor<1x64x128xf32>, tensor<1x128x64xf32>) -> tensor<1x32x64xf32>
      %122 = tensor.empty() : tensor<1x32x64xf32>
      %123 = linalg.add ins(%119, %121 : tensor<1x32x64xf32>, tensor<1x32x64xf32>) outs(%122 : tensor<1x32x64xf32>) -> tensor<1x32x64xf32>
    return %123 : tensor<1x32x64xf32>
  }
  func.func @fn_val_124(%125: tensor<1x4x8xf32>) -> tensor<1x4xf32> attributes {llvm.emit_c_interface} {
      %126 = arith.constant dense<0> : tensor<1x4xi64>
      %129 = arith.constant 0xFF800000 : f32
      %127 = tensor.empty() : tensor<1x4x1xf32>
      %128 = linalg.fill ins(%129 : f32) outs(%127 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
      %130 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%125 : tensor<1x4x8xf32>) outs(%128 : tensor<1x4x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %131 = arith.maximumf %a0, %a1 : f32
        linalg.yield %131 : f32
      } -> tensor<1x4x1xf32>
      %132 = tensor.empty() : tensor<1x4x8xf32>
      %133 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%130 : tensor<1x4x1xf32>) outs(%132 : tensor<1x4x8xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x4x8xf32>
      %134 = tensor.empty() : tensor<1x4x8xf32>
      %135 = linalg.sub ins(%125, %133 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%134 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
      %138 = arith.constant 0xFF800000 : f32
      %136 = tensor.empty() : tensor<1x4x1xf32>
      %137 = linalg.fill ins(%138 : f32) outs(%136 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
      %139 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%125 : tensor<1x4x8xf32>) outs(%137 : tensor<1x4x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %140 = arith.maximumf %a0, %a1 : f32
        linalg.yield %140 : f32
      } -> tensor<1x4x1xf32>
      %141 = tensor.empty() : tensor<1x4x8xf32>
      %142 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%139 : tensor<1x4x1xf32>) outs(%141 : tensor<1x4x8xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x4x8xf32>
      %143 = tensor.empty() : tensor<1x4x8xf32>
      %144 = linalg.sub ins(%125, %142 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%143 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
      %145 = tensor.empty() : tensor<1x4x8xf32>
      %146 = linalg.exp ins(%144 : tensor<1x4x8xf32>) outs(%145 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
      %149 = arith.constant 0.000000e+00 : f32
      %147 = tensor.empty() : tensor<1x4x1xf32>
      %148 = linalg.fill ins(%149 : f32) outs(%147 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
      %150 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
        iterator_types = ["parallel", "parallel", "reduction"]
      } ins(%146 : tensor<1x4x8xf32>) outs(%148 : tensor<1x4x1xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        %151 = arith.addf %a0, %a1 : f32
        linalg.yield %151 : f32
      } -> tensor<1x4x1xf32>
      %152 = tensor.empty() : tensor<1x4x8xf32>
      %153 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
        iterator_types = ["parallel", "parallel", "parallel"]
      } ins(%150 : tensor<1x4x1xf32>) outs(%152 : tensor<1x4x8xf32>) {
      ^bb0(%a0: f32, %a1: f32):
        linalg.yield %a0 : f32
      } -> tensor<1x4x8xf32>
      %154 = tensor.empty() : tensor<1x4x8xf32>
      %155 = linalg.log ins(%153 : tensor<1x4x8xf32>) outs(%154 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
      %156 = tensor.empty() : tensor<1x4x8xf32>
      %157 = linalg.sub ins(%135, %155 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%156 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
      %158 = arith.constant 0 : i64
      %159 = arith.constant 8 : i64
      %160 = tensor.empty() : tensor<1x4xi64>
      %161 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],
        iterator_types = ["parallel", "parallel"]
      } ins(%126 : tensor<1x4xi64>) outs(%160 : tensor<1x4xi64>) {
      ^bb0(%candidate: i64, %_: i64):
        %162 = arith.cmpi sge, %candidate, %158 : i64
        %163 = arith.cmpi slt, %candidate, %159 : i64
        %164 = arith.andi %162, %163 : i1
        cf.assert %164, "take_along_axis index out of bounds"
        linalg.yield %candidate : i64
      } -> tensor<1x4xi64>
      %165 = tensor.empty() : tensor<1x4xf32>
      %166 = linalg.generic {
        indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],
        iterator_types = ["parallel", "parallel"]
      } ins(%161 : tensor<1x4xi64>) outs(%165 : tensor<1x4xf32>) {
      ^bb0(%idx: i64, %_: f32):
        %167 = linalg.index 0 : index
        %168 = linalg.index 1 : index
        %169 = arith.index_cast %idx : i64 to index
        %170 = tensor.extract %157[%167, %168, %169] : tensor<1x4x8xf32>
        linalg.yield %170 : f32
      } -> tensor<1x4xf32>
      %171 = tensor.empty() : tensor<1x4xf32>
      %172 = linalg.negf ins(%166 : tensor<1x4xf32>) outs(%171 : tensor<1x4xf32>) -> tensor<1x4xf32>
    return %172 : tensor<1x4xf32>
  }
  func.func @main() -> (tensor<1x4xf32>, tensor<1x4x8xf32>) {
    %173 = arith.constant dense<0.000000e+00> : tensor<1x4x8xf32>
    %174 = arith.constant dense<0> : tensor<1x4xi64>
    %177 = arith.constant 0xFF800000 : f32
    %175 = tensor.empty() : tensor<1x4x1xf32>
    %176 = linalg.fill ins(%177 : f32) outs(%175 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
    %178 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
      iterator_types = ["parallel", "parallel", "reduction"]
    } ins(%173 : tensor<1x4x8xf32>) outs(%176 : tensor<1x4x1xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      %179 = arith.maximumf %a0, %a1 : f32
      linalg.yield %179 : f32
    } -> tensor<1x4x1xf32>
    %180 = tensor.empty() : tensor<1x4x8xf32>
    %181 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
      iterator_types = ["parallel", "parallel", "parallel"]
    } ins(%178 : tensor<1x4x1xf32>) outs(%180 : tensor<1x4x8xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      linalg.yield %a0 : f32
    } -> tensor<1x4x8xf32>
    %182 = tensor.empty() : tensor<1x4x8xf32>
    %183 = linalg.sub ins(%173, %181 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%182 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %186 = arith.constant 0xFF800000 : f32
    %184 = tensor.empty() : tensor<1x4x1xf32>
    %185 = linalg.fill ins(%186 : f32) outs(%184 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
    %187 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
      iterator_types = ["parallel", "parallel", "reduction"]
    } ins(%173 : tensor<1x4x8xf32>) outs(%185 : tensor<1x4x1xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      %188 = arith.maximumf %a0, %a1 : f32
      linalg.yield %188 : f32
    } -> tensor<1x4x1xf32>
    %189 = tensor.empty() : tensor<1x4x8xf32>
    %190 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
      iterator_types = ["parallel", "parallel", "parallel"]
    } ins(%187 : tensor<1x4x1xf32>) outs(%189 : tensor<1x4x8xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      linalg.yield %a0 : f32
    } -> tensor<1x4x8xf32>
    %191 = tensor.empty() : tensor<1x4x8xf32>
    %192 = linalg.sub ins(%173, %190 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%191 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %193 = tensor.empty() : tensor<1x4x8xf32>
    %194 = linalg.exp ins(%192 : tensor<1x4x8xf32>) outs(%193 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %197 = arith.constant 0.000000e+00 : f32
    %195 = tensor.empty() : tensor<1x4x1xf32>
    %196 = linalg.fill ins(%197 : f32) outs(%195 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
    %198 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
      iterator_types = ["parallel", "parallel", "reduction"]
    } ins(%194 : tensor<1x4x8xf32>) outs(%196 : tensor<1x4x1xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      %199 = arith.addf %a0, %a1 : f32
      linalg.yield %199 : f32
    } -> tensor<1x4x1xf32>
    %200 = tensor.empty() : tensor<1x4x8xf32>
    %201 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
      iterator_types = ["parallel", "parallel", "parallel"]
    } ins(%198 : tensor<1x4x1xf32>) outs(%200 : tensor<1x4x8xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      linalg.yield %a0 : f32
    } -> tensor<1x4x8xf32>
    %202 = tensor.empty() : tensor<1x4x8xf32>
    %203 = linalg.log ins(%201 : tensor<1x4x8xf32>) outs(%202 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %204 = tensor.empty() : tensor<1x4x8xf32>
    %205 = linalg.sub ins(%183, %203 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%204 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %206 = arith.constant 0 : i64
    %207 = arith.constant 8 : i64
    %208 = tensor.empty() : tensor<1x4xi64>
    %209 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],
      iterator_types = ["parallel", "parallel"]
    } ins(%174 : tensor<1x4xi64>) outs(%208 : tensor<1x4xi64>) {
    ^bb0(%candidate: i64, %_: i64):
      %210 = arith.cmpi sge, %candidate, %206 : i64
      %211 = arith.cmpi slt, %candidate, %207 : i64
      %212 = arith.andi %210, %211 : i1
      cf.assert %212, "take_along_axis index out of bounds"
      linalg.yield %candidate : i64
    } -> tensor<1x4xi64>
    %213 = tensor.empty() : tensor<1x4xf32>
    %214 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],
      iterator_types = ["parallel", "parallel"]
    } ins(%209 : tensor<1x4xi64>) outs(%213 : tensor<1x4xf32>) {
    ^bb0(%idx: i64, %_: f32):
      %215 = linalg.index 0 : index
      %216 = linalg.index 1 : index
      %217 = arith.index_cast %idx : i64 to index
      %218 = tensor.extract %205[%215, %216, %217] : tensor<1x4x8xf32>
      linalg.yield %218 : f32
    } -> tensor<1x4xf32>
    %219 = tensor.empty() : tensor<1x4xf32>
    %220 = linalg.negf ins(%214 : tensor<1x4xf32>) outs(%219 : tensor<1x4xf32>) -> tensor<1x4xf32>
    %221 = arith.constant dense<1.000000e+00> : tensor<1x4xf32>
    %222 = arith.constant dense<1.000000e+00> : tensor<1x4xf32>
    %223 = tensor.empty() : tensor<1x4xf32>
    %224 = linalg.negf ins(%222 : tensor<1x4xf32>) outs(%223 : tensor<1x4xf32>) -> tensor<1x4xf32>
    %225 = arith.constant 0 : i64
    %226 = arith.constant 8 : i64
    %227 = tensor.empty() : tensor<1x4xi64>
    %228 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1) -> (d0, d1)>, affine_map<(d0, d1) -> (d0, d1)>],
      iterator_types = ["parallel", "parallel"]
    } ins(%174 : tensor<1x4xi64>) outs(%227 : tensor<1x4xi64>) {
    ^bb0(%candidate: i64, %_: i64):
      %229 = arith.cmpi sge, %candidate, %225 : i64
      %230 = arith.cmpi slt, %candidate, %226 : i64
      %231 = arith.andi %229, %230 : i1
      cf.assert %231, "scatter_along_axis index out of bounds"
      linalg.yield %candidate : i64
    } -> tensor<1x4xi64>
    %232 = tensor.empty() : tensor<1x4x8xf32>
    %233 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1)>, affine_map<(d0, d1, d2) -> (d0, d1)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
      iterator_types = ["parallel", "parallel", "parallel"]
    } ins(%228, %224 : tensor<1x4xi64>, tensor<1x4xf32>) outs(%232 : tensor<1x4x8xf32>) {
    ^bb0(%idx: i64, %upd: f32, %_: f32):
      %234 = linalg.index 2 : index
      %235 = arith.index_cast %234 : index to i64
      %236 = arith.cmpi eq, %idx, %235 : i64
      %237 = arith.constant 0.000000e+00 : f32
      %238 = arith.select %236, %upd, %237 : f32
      linalg.yield %238 : f32
    } -> tensor<1x4x8xf32>
    %239 = tensor.empty() : tensor<1x4x8xf32>
    %240 = linalg.exp ins(%205 : tensor<1x4x8xf32>) outs(%239 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %243 = arith.constant 0.000000e+00 : f32
    %241 = tensor.empty() : tensor<1x4x1xf32>
    %242 = linalg.fill ins(%243 : f32) outs(%241 : tensor<1x4x1xf32>) -> tensor<1x4x1xf32>
    %244 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (d0, d1, d2)>, affine_map<(d0, d1, d2) -> (d0, d1, 0)>],
      iterator_types = ["parallel", "parallel", "reduction"]
    } ins(%233 : tensor<1x4x8xf32>) outs(%242 : tensor<1x4x1xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      %245 = arith.addf %a0, %a1 : f32
      linalg.yield %245 : f32
    } -> tensor<1x4x1xf32>
    %246 = tensor.empty() : tensor<1x4x8xf32>
    %247 = linalg.generic {
      indexing_maps = [affine_map<(d0, d1, d2) -> (0, d1, 0)>, affine_map<(d0, d1, d2) -> (d0, d1, d2)>],
      iterator_types = ["parallel", "parallel", "parallel"]
    } ins(%244 : tensor<1x4x1xf32>) outs(%246 : tensor<1x4x8xf32>) {
    ^bb0(%a0: f32, %a1: f32):
      linalg.yield %a0 : f32
    } -> tensor<1x4x8xf32>
    %248 = tensor.empty() : tensor<1x4x8xf32>
    %249 = linalg.mul ins(%247, %240 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%248 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    %250 = tensor.empty() : tensor<1x4x8xf32>
    %251 = linalg.sub ins(%233, %249 : tensor<1x4x8xf32>, tensor<1x4x8xf32>) outs(%250 : tensor<1x4x8xf32>) -> tensor<1x4x8xf32>
    return %220, %251 : tensor<1x4xf32>, tensor<1x4x8xf32>
  }
}