torch/csrc/jit/interpreter.cpp
// this currently just _removes_ the trip count inputs and checks they are
// unused. In the future they will be desugared into normal arithmetic to
// provide a loop counter
this currently just _removes_ the trip count inputs and checks they are
unused. In the future they will be desugared into normal arithmetic to
provide a loop counter
this currently just _removes_ the trip count inputs and checks they are unused . In the future they will be desugared into normal arithmetic to provide a loop counter
void desugarTripCounts(Block * b) {
  for(auto n : b->nodes()) {
    if(n->kind() == prim::Loop) {
      auto g = n->owningGraph();
      auto body_block = n->blocks()[0];
      Value* block_trip_count_input = body_block->inputs()[0];
      n->insertOutput(0);
      Value* max_trip_count_value = n->input(0);
      {
        WithInsertPoint guard(n);
        Value* initial_trip_count = g->insertConstant(0);
        n->removeInput(0);
        n->insertInput(1, initial_trip_count);
        Value* new_cond = createTripCountConjunctiveCondition(
            g, initial_trip_count, max_trip_count_value, n->input(0));
        n->replaceInput(0, new_cond);
      }
      {
        WithInsertPoint guard(body_block);
        Value* const_one = g->insertConstant(1);
        Value* inc_trip_count =
            g->insertNode(g->create(
                    aten::add, {block_trip_count_input, const_one}, 1))
             ->output()->setType(IntType::get());
        body_block->insertOutput(1, inc_trip_count);
        Value* body_cond = createTripCountConjunctiveCondition(
            g, inc_trip_count, max_trip_count_value, body_block->outputs()[0]);
        body_block->eraseOutput(0);
        body_block->insertOutput(0, body_cond);
      }
    }
    for(auto sb : n->blocks()) {
      desugarTripCounts(sb);
    }
  }
}
void desugarTripCounts ( Block * b ) { for ( auto n : b -> nodes ( ) ) { if ( n -> kind ( ) == prim :: Loop ) { auto g = n -> owningGraph ( ) ; auto body_block = n -> blocks ( ) [ 0 ] ; Value * block_trip_count_input = body_block -> inputs ( ) [ 0 ] ; n -> insertOutput ( 0 ) ; Value * max_trip_count_value = n -> input ( 0 ) ; { WithInsertPoint guard ( n ) ; Value * initial_trip_count = g -> insertConstant ( 0 ) ; n -> removeInput ( 0 ) ; n -> insertInput ( 1 , initial_trip_count ) ; Value * new_cond = createTripCountConjunctiveCondition ( g , initial_trip_count , max_trip_count_value , n -> input ( 0 ) ) ; n -> replaceInput ( 0 , new_cond ) ; } { WithInsertPoint guard ( body_block ) ; Value * const_one = g -> insertConstant ( 1 ) ; Value * inc_trip_count = g -> insertNode ( g -> create ( aten :: add , { block_trip_count_input , const_one } , 1 ) ) -> output ( ) -> setType ( IntType :: get ( ) ) ; body_block -> insertOutput ( 1 , inc_trip_count ) ; Value * body_cond = createTripCountConjunctiveCondition ( g , inc_trip_count , max_trip_count_value , body_block -> outputs ( ) [ 0 ] ) ; body_block -> eraseOutput ( 0 ) ; body_block -> insertOutput ( 0 , body_cond ) ; } } for ( auto sb : n -> blocks ( ) ) { desugarTripCounts ( sb ) ; } } }
this currently just _removes_ the trip count inputs and checks they are
unused.
this currently just _removes_ the trip count inputs and checks they are unused .
// Treat loop iteration number as a loop-carried dependency. We emit an // increment at the end of the body block. // int i = 0 // Set up initial iteration number value for loop-carried dependency // Input 0 is now initial termination condition, insert this after that. // LCD's start at index 1. // Trip count is now a loop carried dependency. We emit an op to // increment the trip count at the end of the body. Then, emit the same // conjunctive stopping condition as above.