torch/csrc/jit/passes/to_batch.cpp
// prim::If transformation:
// elif is not supported
//
// transformation example:
// @torch.jit.batch(batch_size=4)
// def batch_if(a, b):
//     if a > b:
//         a += b
//     else:
//         a -= b
//     return a
//
// original graph:
// graph(%a.1 : Dynamic
//       %b : Dynamic) {
//   %2 : Dynamic = aten::gt(%a.1, %b)
//   %a : Dynamic = prim::If(%2)
//     block0() {
//       %a.2 : Dynamic = aten::add[alpha={1}](%a.1, %b)
//       -> (%a.2)
//     }
//     block1() {
//       %a.3 : Dynamic = aten::sub[alpha={1}](%a.1, %b)
//       -> (%a.3)
//     }
//   return (%a);
// }
//
// transformed graph:
// graph(%a.1_data : Dynamic
//       %a.1_mask : Dynamic
//       %a.1_dims : Dynamic
//       %b_data : Dynamic
//       %b_mask : Dynamic
//       %b_dims : Dynamic) {
//   %6 : Dynamic = aten::gt(%a.1_data, %b_data)  // calculate condition
//   %7 : Dynamic = aten::mul(%a.1_mask, %b_mask)
//   %8 : Dynamic = aten::__or__(%a.1_dims, %b_dims)
//   %9 : int = prim::TensorToNum(%6)
//   %10 : Long() = prim::Constant[value={1}]()  // if_block
//   %alpha.1 : float = prim::TensorToNum(%10)
//   %data.1 : Dynamic = aten::add(%a.1_data, %b_data, %alpha.1)
//   %mask.1 : Dynamic = aten::mul(%a.1_mask, %b_mask)
//   %dims.1 : Dynamic = aten::__or__(%a.1_dims, %b_dims)
//   %15 : Long() = prim::Constant[value={1}]()  // else_block
//   %alpha : float = prim::TensorToNum(%15)
//   %data.4 : Dynamic = aten::sub(%a.1_data, %b_data, %alpha)
//   %mask : Dynamic = aten::mul(%a.1_mask, %b_mask)
//   %dims : Dynamic = aten::__or__(%a.1_dims, %b_dims)
//   %20 : Dynamic = aten::type_as(%7, %6)   // combine two outputs (batch_where)
//   %cond_mask.1 : Dynamic = aten::mul(%6, %20)
//   %22 : int = aten::dim(%cond_mask.1)
//   %23 : int = prim::Constant[value=1]()
//   %24 : int = aten::eq(%22, %23)
//   %cond_data : Dynamic, %cond_mask : Dynamic, %data : Dynamic = prim::If(%24)
//     block0() {
//       %28 : int = aten::dim(%data.1)
//       %29 : int = prim::Constant[value=1]()
//       %30 : int = aten::sub(%28, %29)
//       %31 : int = prim::Constant[value=1]()
//       %data.3 : Dynamic = prim::Loop(%30, %31, %cond_mask.1)
//         block0(%_ : int, %34 : Dynamic) {
//           %35 : int = prim::Constant[value=1]()
//           %36 : int = aten::neg(%35)
//           %data.2 : Dynamic = aten::unsqueeze(%34, %36)
//           %38 : int = prim::Constant[value=1]()
//           -> (%38, %data.2)
//         }
//       %cond_data.1 : Dynamic = aten::expand_as(%data.3, %data.1)
//       %cond_mask.2 : Dynamic = aten::expand_as(%data.3, %mask.1)
//       -> (%cond_data.1, %cond_mask.2, %data.3)
//     }
//     block1() {
//       -> (%cond_mask.1, %cond_mask.1, %cond_mask.1)
//     }
//   %res_data : Dynamic = aten::where(%cond_data, %data.1, %data.4)
//   %res_mask : Dynamic = aten::where(%cond_mask, %mask.1, %mask)
//   %res_dims : Dynamic = aten::__or__(%dims.1, %dims)
//   return (%res_data, %res_mask, %res_dims);
// }
:If transformation:
elif is not supported

transformation example.
: If transformation : elif is not supported transformation example .
void ToBatch::visitIf(Node* n, Block* block, Block* res_block){
  toBatch(n->blocks()[0], res_block);
  toBatch(n->blocks()[1], res_block);
  for(size_t i = 0; i < n->outputs().size(); i++){
    std::vector<Value*> inputs;
    if(batch_map.find(n->input()) == batch_map.end()){  
      inputs.push_back(rn_env.at(n->input()));
    }
    else{  
      auto cond = batch_map.at(n->input());
      inputs.insert(inputs.end(), cond.begin(), cond.end());
    }
    auto if_output = batch_map.at(n->blocks()[0]->outputs()[i]);
    inputs.insert(inputs.end(), if_output.begin(), if_output.end());
    auto else_output = batch_map.at(n->blocks()[1]->outputs()[i]);
    inputs.insert(inputs.end(), else_output.begin(), else_output.end());
    auto outputs = script::inlineCallTo(*res_block->owningGraph(), *getBatchOperator("where", inputs.size()), inputs);
    batch_map[n->outputs()[i]] = outputs;
  }
}
void ToBatch :: visitIf ( Node * n , Block * block , Block * res_block ) { toBatch ( n -> blocks ( ) [ 0 ] , res_block ) ; toBatch ( n -> blocks ( ) [ 1 ] , res_block ) ; for ( size_t i = 0 ; i < n -> outputs ( ) . size ( ) ; i ++ ) { std :: vector < Value * > inputs ; if ( batch_map . find ( n -> input ( ) ) == batch_map . end ( ) ) { inputs . push_back ( rn_env . at ( n -> input ( ) ) ) ; } else { auto cond = batch_map . at ( n -> input ( ) ) ; inputs . insert ( inputs . end ( ) , cond . begin ( ) , cond . end ( ) ) ; } auto if_output = batch_map . at ( n -> blocks ( ) [ 0 ] -> outputs ( ) [ i ] ) ; inputs . insert ( inputs . end ( ) , if_output . begin ( ) , if_output . end ( ) ) ; auto else_output = batch_map . at ( n -> blocks ( ) [ 1 ] -> outputs ( ) [ i ] ) ; inputs . insert ( inputs . end ( ) , else_output . begin ( ) , else_output . end ( ) ) ; auto outputs = script :: inlineCallTo ( * res_block -> owningGraph ( ) , * getBatchOperator ( " " , inputs . size ( ) ) , inputs ) ; batch_map [ n -> outputs ( ) [ i ] ] = outputs ; } }
prim::If transformation:
elif is not supported
prim :: If transformation : elif is not supported
// combine results from two if paths // cond is scalar // cond is tensor