Status CanContractEdgeDeadnessCheck()

in ngraph_bridge/assign_clusters.cc [114:189]


Status CanContractEdgeDeadnessCheck(
    Edge* edge, const std::map<Node*, std::shared_ptr<Cluster>>& cluster_map,
    bool& is_deadness_ok) {
  Node* src = edge->src();
  Node* dst = edge->dst();

  string src_predicate = cluster_map.at(src)->predicate_string;
  string dst_predicate = cluster_map.at(dst)->predicate_string;

  // If the node marked for clustering has CONTROL_FLOW_PRED_STRING, it
  // breaks our assumption that all supported ops are data flow ops
  if (DeadnessAnalysis::IsControlFlowPredString(src_predicate) ||
      DeadnessAnalysis::IsControlFlowPredString(dst_predicate)) {
    return errors::Internal(
        "Attempting to contract edge with control flow ops : ",
        edge->DebugString());
  }

  // Case src X , dst Y , X!=Y // cannot be contracted
  if (!DeadnessAnalysis::IsTruePredString(src_predicate) &&
      !DeadnessAnalysis::IsTruePredString(dst_predicate) &&
      src_predicate != dst_predicate) {
    is_deadness_ok = false;
    return Status::OK();
  }

  // Case src X , dst True // invalid scenario
  // If src has Non-True Predicate and dst has True Predicate, it implies that
  // the dst node is control flow
  if (!DeadnessAnalysis::IsTruePredString(src_predicate) &&
      DeadnessAnalysis::IsTruePredString(dst_predicate)) {
    return errors::Internal("Attempting to cluster control-flow node ",
                            dst->name(), "[", dst->type_string(), "]");
  }

  // Case src True, dst Y
  // If this edge is contracted, all the outputs of the merged cluster will
  // have the predicate Y (True & Y = Y). Hence contraction is possible only
  // when, all outputs of the src cluster (other than the current edge) have the
  // predicate Y
  if (DeadnessAnalysis::IsTruePredString(src_predicate)) {
    auto src_cluster_out_edges = cluster_map.at(src)->outgoing_edges;
    bool found_same_out_preds = true;
    std::string pred_check = dst_predicate;

    for (const Edge* src_cluster_edge : src_cluster_out_edges) {
      if (src_cluster_edge == edge) {
        continue;
      }
      Node* src_cluster_dst = src_cluster_edge->dst();
      std::string src_cluster_dst_pred =
          cluster_map.at(src_cluster_dst)->predicate_string;
      // Note that if dst predicate is True, then it does not matter what the
      // src_cluster_dst_pred is; After merge the merged cluster will always
      // have a less strict predicate, True (since True is the least strict
      // predicate)
      if (!DeadnessAnalysis::IsTruePredString(pred_check) &&
          pred_check != src_cluster_dst_pred) {
        found_same_out_preds = false;
        break;
      }
    }
    // Cannot contract this edge
    if (!found_same_out_preds) {
      is_deadness_ok = false;
      return Status::OK();
    }
  }

  // Case src X, dst Y, X==Y
  // Case src True, dst Y(Y can be True), all other output edges from src
  // cluster have pred Y
  // Ok to contract
  is_deadness_ok = true;
  return Status::OK();
}