@@ -129,8 +129,8 @@ def __init__(self, ids: set[str]) -> None:
129129 self .id = SCC .id_counter
130130 SCC .id_counter += 1
131131 self .mod_ids = ids
132+ self .deps : set [int ] = set ()
132133 self .not_ready_deps : set [int ] = set ()
133- self .transitive_deps : list [int ] = []
134134 self .direct_dependents : list [int ] = []
135135
136136
@@ -738,8 +738,9 @@ def __init__(
738738 # Number of times we used GC optimization hack for fresh SCCs.
739739 self .gc_freeze_cycles = 0
740740 self .scc_by_id : dict [int , SCC ] = {}
741+ self .top_order : list [int ] = []
741742 self .scc_queue : list [SCC ] = []
742- self .done_sccs : set [SCC ] = set ()
743+ self .done_sccs : set [int ] = set ()
743744
744745 def dump_stats (self ) -> None :
745746 if self .options .dump_build_stats :
@@ -3326,15 +3327,16 @@ def process_graph(graph: Graph, manager: BuildManager) -> None:
33263327 "Found %d SCCs; largest has %d nodes" % (len (sccs ), max (len (scc .mod_ids ) for scc in sccs ))
33273328 )
33283329 for scc in sccs :
3329- pass # print("SCC", scc.id, scc.mod_ids, scc.transitive_deps , scc.direct_dependents)
3330+ pass # print("SCC", scc.id, scc.mod_ids, scc.deps , scc.direct_dependents)
33303331
33313332 scc_by_id = {scc .id : scc for scc in sccs }
33323333 manager .scc_by_id = scc_by_id
3334+ manager .top_order = [scc .id for scc in sccs ]
33333335
33343336 ready = []
33353337 not_ready = []
33363338 for scc in sccs :
3337- if not scc .transitive_deps :
3339+ if not scc .deps :
33383340 ready .append (scc )
33393341 else :
33403342 not_ready .append (scc )
@@ -3423,13 +3425,20 @@ def process_fresh_modules(graph: Graph, modules: list[str], manager: BuildManage
34233425
34243426def process_stale_scc (graph : Graph , ascc : SCC , manager : BuildManager ) -> None :
34253427 """Process the modules in one SCC from source code."""
3426- fresh_sccs = [
3427- dep
3428- for id in ascc .transitive_deps
3429- if (dep := manager .scc_by_id [id ]) not in manager .done_sccs
3430- ]
3431- if fresh_sccs :
3432- manager .log (f"Processing { len (fresh_sccs )} fresh SCCs" )
3428+ missing_sccs = set ()
3429+ sccs_to_find = ascc .deps .copy ()
3430+ while sccs_to_find :
3431+ dep_scc = sccs_to_find .pop ()
3432+ if dep_scc in manager .done_sccs or dep_scc in missing_sccs :
3433+ continue
3434+ missing_sccs .add (dep_scc )
3435+ sccs_to_find .update (manager .scc_by_id [dep_scc ].deps )
3436+
3437+ if missing_sccs :
3438+ fresh_sccs_to_load = [
3439+ manager .scc_by_id [sid ] for sid in manager .top_order if sid in missing_sccs
3440+ ]
3441+ manager .log (f"Processing { len (fresh_sccs_to_load )} fresh SCCs" )
34333442 if (
34343443 not manager .options .test_env
34353444 and platform .python_implementation () == "CPython"
@@ -3444,9 +3453,9 @@ def process_stale_scc(graph: Graph, ascc: SCC, manager: BuildManager) -> None:
34443453 # libraries, like torch.
34453454 gc .collect ()
34463455 gc .disable ()
3447- for prev_scc in fresh_sccs :
3448- manager .done_sccs .add (prev_scc )
3449- process_fresh_modules (graph , list (prev_scc .mod_ids ), manager )
3456+ for prev_scc in fresh_sccs_to_load :
3457+ manager .done_sccs .add (prev_scc . id )
3458+ process_fresh_modules (graph , sorted (prev_scc .mod_ids ), manager )
34503459 if (
34513460 not manager .options .test_env
34523461 and platform .python_implementation () == "CPython"
@@ -3514,7 +3523,7 @@ def process_stale_scc(graph: Graph, ascc: SCC, manager: BuildManager) -> None:
35143523 }
35153524 meta ["error_lines" ] = errors_by_id .get (id , [])
35163525 write_cache_meta (meta , manager , meta_json )
3517- manager .done_sccs .add (ascc )
3526+ manager .done_sccs .add (ascc . id )
35183527
35193528
35203529def prepare_sccs (raw_sccs : Iterator [set [str ]], edges : dict [str , list [str ]]) -> dict [SCC , set [SCC ]]:
@@ -3530,6 +3539,7 @@ def prepare_sccs(raw_sccs: Iterator[set[str]], edges: dict[str, list[str]]) -> d
35303539 for scc in sccs :
35313540 scc_deps_map [scc ].discard (scc )
35323541 for dep_scc in scc_deps_map [scc ]:
3542+ scc .deps .add (dep_scc .id )
35333543 scc .not_ready_deps .add (dep_scc .id )
35343544 return scc_deps_map
35353545
@@ -3566,10 +3576,6 @@ def sorted_components(
35663576 for scc in sorted_ready :
35673577 for dep in scc_dep_map [scc ]:
35683578 dep .direct_dependents .append (scc .id )
3569- new_trans_deps = [d for d in dep .transitive_deps if d not in scc .transitive_deps ]
3570- scc .transitive_deps .extend (new_trans_deps )
3571- if dep .id not in scc .transitive_deps :
3572- scc .transitive_deps .append (dep .id )
35733579 res .extend (sorted_ready )
35743580 return res
35753581
0 commit comments