Return the index list of relevant operator to produce target blob from source blob, if there's no dependency, return empty list.
(ssa, versioned_target, versioned_source)
| 823 | |
| 824 | |
| 825 | def _get_dependency_chain(ssa, versioned_target, versioned_source): |
| 826 | """ |
| 827 | Return the index list of relevant operator to produce target blob from source blob, |
| 828 | if there's no dependency, return empty list. |
| 829 | """ |
| 830 | |
| 831 | # finding all paths between nodes can be O(N!), thus we can only search |
| 832 | # in the subgraph using the op starting from the first consumer of source blob |
| 833 | # to the producer of the target blob. |
| 834 | consumer_map = get_consumer_map(ssa) |
| 835 | producer_map = get_producer_map(ssa) |
| 836 | start_op = min(x[0] for x in consumer_map[versioned_source]) - 15 |
| 837 | end_op = ( |
| 838 | producer_map[versioned_target][0] + 15 if versioned_target in producer_map else start_op |
| 839 | ) |
| 840 | sub_graph_ssa = ssa[start_op : end_op + 1] |
| 841 | if len(sub_graph_ssa) > 30: |
| 842 | logger.warning( |
| 843 | "Subgraph bebetween {} and {} is large (from op#{} to op#{}), it" |
| 844 | " might take non-trival time to find all paths between them.".format( |
| 845 | versioned_source, versioned_target, start_op, end_op |
| 846 | ) |
| 847 | ) |
| 848 | |
| 849 | dag = DiGraph.from_ssa(sub_graph_ssa) |
| 850 | paths = dag.get_all_paths(versioned_source, versioned_target) # include two ends |
| 851 | ops_in_paths = [[producer_map[blob][0] for blob in path[1:]] for path in paths] |
| 852 | return sorted(set().union(*[set(ops) for ops in ops_in_paths])) |
| 853 | |
| 854 | |
| 855 | def identify_reshape_sub_graph(predict_net: caffe2_pb2.NetDef) -> List[List[int]]: |
no test coverage detected