caffe2/core/nomnigraph/Representations/NeuralNet.cc
// TODO: move this to more generic location.
// TODO: [algo] improve this algorithm, as it is horrendously inefficient.
move this to more generic location.
TODO: [algo] improve this algorithm, as it is horrendously inefficient.
move this to more generic location . TODO : [ algo ] improve this algorithm as it is horrendously inefficient .
void coalesceInsertedDataDependencies(repr::NNModule* m) {
  size_t oldSize = 0;
  size_t newSize = 0;
  do {
    oldSize = newSize;
    newSize = coalesceInsertedDataDependenciesHelper(m);
  } while (newSize != oldSize);
  auto cfTrackedNodes = getTrackedNodes(m->controlFlow);
  std::unordered_set<repr::NNGraph::NodeRef> dfNodes;
  for (auto node : m->dataFlow.getMutableNodes()) {
    if (repr::nn::is<NeuralNetOperator>(node) && !cfTrackedNodes.count(node)) {
      dfNodes.insert(node);
    }
  }
  auto newBbNode = m->controlFlow.createNode(
      util::make_unique<repr::BasicBlockType<repr::NNGraph>>());
  auto sccs = algorithm::tarjans(&m->dataFlow);
  for (auto iter = sccs.rbegin(); iter != sccs.rend(); ++iter) {
    for (auto node : iter->getNodes()) {
      if (dfNodes.count(node)) {
        auto currentBasicBlock = newBbNode->mutableData()->get();
        currentBasicBlock->pushInstructionNode(node);
      }
    }
  }
  for (auto& bbNode : m->controlFlow.getMutableNodes()) {
    auto bb = bbNode->mutableData()->get();
    std::unordered_set<repr::NNGraph::NodeRef> seen;
    for (auto instr_iter = bb->getInstructions().begin();
         instr_iter != bb->getInstructions().end();
         ++instr_iter) {
      auto instr = *instr_iter;
      for (auto& output : getOutputs(instr)) {
        for (auto& consumer : getConsumers(output)) {
          if (seen.count(consumer)) {
            bb->moveInstructionBefore(instr, consumer);
          }
        }
      }
      seen.insert(instr);
    }
  }
}
void coalesceInsertedDataDependencies ( repr :: NNModule * m ) { size_t oldSize = 0 ; size_t newSize = 0 ; do { oldSize = newSize ; newSize = coalesceInsertedDataDependenciesHelper ( m ) ; } while ( newSize != oldSize ) ; auto cfTrackedNodes = getTrackedNodes ( m -> controlFlow ) ; std :: unordered_set < repr :: NNGraph :: NodeRef > dfNodes ; for ( auto node : m -> dataFlow . getMutableNodes ( ) ) { if ( repr :: nn :: is < NeuralNetOperator > ( node ) && ! cfTrackedNodes . count ( node ) ) { dfNodes . insert ( node ) ; } } auto newBbNode = m -> controlFlow . createNode ( util :: make_unique < repr :: BasicBlockType < repr :: NNGraph > > ( ) ) ; auto sccs = algorithm :: tarjans ( & m -> dataFlow ) ; for ( auto iter = sccs . rbegin ( ) ; iter != sccs . rend ( ) ; ++ iter ) { for ( auto node : iter -> getNodes ( ) ) { if ( dfNodes . count ( node ) ) { auto currentBasicBlock = newBbNode -> mutableData ( ) -> get ( ) ; currentBasicBlock -> pushInstructionNode ( node ) ; } } } for ( auto & bbNode : m -> controlFlow . getMutableNodes ( ) ) { auto bb = bbNode -> mutableData ( ) -> get ( ) ; std :: unordered_set < repr :: NNGraph :: NodeRef > seen ; for ( auto instr_iter = bb -> getInstructions ( ) . begin ( ) ; instr_iter != bb -> getInstructions ( ) . end ( ) ; ++ instr_iter ) { auto instr = * instr_iter ; for ( auto & output : getOutputs ( instr ) ) { for ( auto & consumer : getConsumers ( output ) ) { if ( seen . count ( consumer ) ) { bb -> moveInstructionBefore ( instr , consumer ) ; } } } seen . insert ( instr ) ; } } }
TODO: move this to more generic location.
TODO : move this to more generic location .
// Now we track new nodes that have no relationship to the old CFGraph // Finally we reconcile any data dependency issues (if we can). // This cannot be auto&, TODO figure out why