Split ScheduleGraph::process_configs function (adopted) (#12435)
Adoption of #10617, resolved conflicts with main --------- Co-authored-by: Stepan Koltsov <stepan.koltsov@gmail.com>
This commit is contained in:
		
							parent
							
								
									1323de7cd7
								
							
						
					
					
						commit
						e9dc270d68
					
				| @ -661,6 +661,42 @@ impl ScheduleGraph { | ||||
|         &self.conflicting_systems | ||||
|     } | ||||
| 
 | ||||
|     fn process_config<T: ProcessNodeConfig>( | ||||
|         &mut self, | ||||
|         config: NodeConfig<T>, | ||||
|         collect_nodes: bool, | ||||
|     ) -> ProcessConfigsResult { | ||||
|         ProcessConfigsResult { | ||||
|             densely_chained: true, | ||||
|             nodes: collect_nodes | ||||
|                 .then_some(T::process_config(self, config)) | ||||
|                 .into_iter() | ||||
|                 .collect(), | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     fn apply_collective_conditions<T: ProcessNodeConfig>( | ||||
|         &mut self, | ||||
|         configs: &mut [NodeConfigs<T>], | ||||
|         collective_conditions: Vec<BoxedCondition>, | ||||
|     ) { | ||||
|         if !collective_conditions.is_empty() { | ||||
|             if let [config] = configs { | ||||
|                 for condition in collective_conditions { | ||||
|                     config.run_if_dyn(condition); | ||||
|                 } | ||||
|             } else { | ||||
|                 let set = self.create_anonymous_set(); | ||||
|                 for config in configs.iter_mut() { | ||||
|                     config.in_set_inner(set.intern()); | ||||
|                 } | ||||
|                 let mut set_config = SystemSetConfig::new(set.intern()); | ||||
|                 set_config.conditions.extend(collective_conditions); | ||||
|                 self.configure_set_inner(set_config).unwrap(); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     /// Adds the config nodes to the graph.
 | ||||
|     ///
 | ||||
|     /// `collect_nodes` controls whether the `NodeId`s of the processed config nodes are stored in the returned [`ProcessConfigsResult`].
 | ||||
| @ -676,157 +712,75 @@ impl ScheduleGraph { | ||||
|         collect_nodes: bool, | ||||
|     ) -> ProcessConfigsResult { | ||||
|         match configs { | ||||
|             NodeConfigs::NodeConfig(config) => { | ||||
|                 let node_id = T::process_config(self, config); | ||||
|                 if collect_nodes { | ||||
|                     ProcessConfigsResult { | ||||
|                         densely_chained: true, | ||||
|                         nodes: vec![node_id], | ||||
|                     } | ||||
|                 } else { | ||||
|                     ProcessConfigsResult { | ||||
|                         densely_chained: true, | ||||
|                         nodes: Vec::new(), | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|             NodeConfigs::NodeConfig(config) => self.process_config(config, collect_nodes), | ||||
|             NodeConfigs::Configs { | ||||
|                 mut configs, | ||||
|                 collective_conditions, | ||||
|                 chained, | ||||
|             } => { | ||||
|                 let more_than_one_entry = configs.len() > 1; | ||||
|                 if !collective_conditions.is_empty() { | ||||
|                     if more_than_one_entry { | ||||
|                         let set = self.create_anonymous_set(); | ||||
|                         for config in &mut configs { | ||||
|                             config.in_set_inner(set.intern()); | ||||
|                         } | ||||
|                         let mut set_config = SystemSetConfig::new(set.intern()); | ||||
|                         set_config.conditions.extend(collective_conditions); | ||||
|                         self.configure_set_inner(set_config).unwrap(); | ||||
|                     } else { | ||||
|                         for condition in collective_conditions { | ||||
|                             configs[0].run_if_dyn(condition); | ||||
|                         } | ||||
|                     } | ||||
|                 } | ||||
|                 let mut config_iter = configs.into_iter(); | ||||
|                 let mut nodes_in_scope = Vec::new(); | ||||
|                 let mut densely_chained = true; | ||||
|                 if chained == Chain::Yes || chained == Chain::YesIgnoreDeferred { | ||||
|                     let Some(prev) = config_iter.next() else { | ||||
|                 self.apply_collective_conditions(&mut configs, collective_conditions); | ||||
| 
 | ||||
|                 let ignore_deferred = matches!(chained, Chain::YesIgnoreDeferred); | ||||
|                 let chained = matches!(chained, Chain::Yes | Chain::YesIgnoreDeferred); | ||||
| 
 | ||||
|                 // Densely chained if
 | ||||
|                 // * chained and all configs in the chain are densely chained, or
 | ||||
|                 // * unchained with a single densely chained config
 | ||||
|                 let mut densely_chained = chained || configs.len() == 1; | ||||
|                 let mut configs = configs.into_iter(); | ||||
|                 let mut nodes = Vec::new(); | ||||
| 
 | ||||
|                 let Some(first) = configs.next() else { | ||||
|                     return ProcessConfigsResult { | ||||
|                         nodes: Vec::new(), | ||||
|                             densely_chained: true, | ||||
|                         densely_chained, | ||||
|                     }; | ||||
|                 }; | ||||
|                     let mut previous_result = self.process_configs(prev, true); | ||||
|                     densely_chained = previous_result.densely_chained; | ||||
|                     for current in config_iter { | ||||
|                         let current_result = self.process_configs(current, true); | ||||
|                         densely_chained = densely_chained && current_result.densely_chained; | ||||
|                         match ( | ||||
|                             previous_result.densely_chained, | ||||
|                             current_result.densely_chained, | ||||
|                         ) { | ||||
|                             // Both groups are "densely" chained, so we can simplify the graph by only
 | ||||
|                             // chaining the last in the previous list to the first in the current list
 | ||||
|                             (true, true) => { | ||||
|                                 let last_in_prev = previous_result.nodes.last().unwrap(); | ||||
|                                 let first_in_current = current_result.nodes.first().unwrap(); | ||||
|                                 self.dependency.graph.add_edge( | ||||
|                                     *last_in_prev, | ||||
|                                     *first_in_current, | ||||
|                                     (), | ||||
|                                 ); | ||||
|                 let mut previous_result = self.process_configs(first, collect_nodes || chained); | ||||
|                 densely_chained &= previous_result.densely_chained; | ||||
| 
 | ||||
|                                 if chained == Chain::YesIgnoreDeferred { | ||||
|                                     self.no_sync_edges | ||||
|                                         .insert((*last_in_prev, *first_in_current)); | ||||
|                                 } | ||||
|                             } | ||||
|                             // The previous group is "densely" chained, so we can simplify the graph by only
 | ||||
|                             // chaining the last item from the previous list to every item in the current list
 | ||||
|                             (true, false) => { | ||||
|                                 let last_in_prev = previous_result.nodes.last().unwrap(); | ||||
|                                 for current_node in ¤t_result.nodes { | ||||
|                                     self.dependency.graph.add_edge( | ||||
|                                         *last_in_prev, | ||||
|                                         *current_node, | ||||
|                                         (), | ||||
|                                     ); | ||||
|                 for current in configs { | ||||
|                     let current_result = self.process_configs(current, collect_nodes || chained); | ||||
|                     densely_chained &= current_result.densely_chained; | ||||
| 
 | ||||
|                                     if chained == Chain::YesIgnoreDeferred { | ||||
|                                         self.no_sync_edges.insert((*last_in_prev, *current_node)); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             // The current list is currently "densely" chained, so we can simplify the graph by
 | ||||
|                             // only chaining every item in the previous list to the first item in the current list
 | ||||
|                             (false, true) => { | ||||
|                                 let first_in_current = current_result.nodes.first().unwrap(); | ||||
|                                 for previous_node in &previous_result.nodes { | ||||
|                                     self.dependency.graph.add_edge( | ||||
|                                         *previous_node, | ||||
|                                         *first_in_current, | ||||
|                                         (), | ||||
|                                     ); | ||||
|                     if chained { | ||||
|                         // if the current result is densely chained, we only need to chain the first node
 | ||||
|                         let current_nodes = if current_result.densely_chained { | ||||
|                             ¤t_result.nodes[..1] | ||||
|                         } else { | ||||
|                             ¤t_result.nodes | ||||
|                         }; | ||||
|                         // if the previous result was densely chained, we only need to chain the last node
 | ||||
|                         let previous_nodes = if previous_result.densely_chained { | ||||
|                             &previous_result.nodes[previous_result.nodes.len() - 1..] | ||||
|                         } else { | ||||
|                             &previous_result.nodes | ||||
|                         }; | ||||
| 
 | ||||
|                                     if chained == Chain::YesIgnoreDeferred { | ||||
|                                         self.no_sync_edges | ||||
|                                             .insert((*previous_node, *first_in_current)); | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                             // Neither of the lists are "densely" chained, so we must chain every item in the first
 | ||||
|                             // list to every item in the second list
 | ||||
|                             (false, false) => { | ||||
|                                 for previous_node in &previous_result.nodes { | ||||
|                                     for current_node in ¤t_result.nodes { | ||||
|                                         self.dependency.graph.add_edge( | ||||
|                                             *previous_node, | ||||
|                                             *current_node, | ||||
|                                             (), | ||||
|                                         ); | ||||
|                         for previous_node in previous_nodes { | ||||
|                             for current_node in current_nodes { | ||||
|                                 self.dependency | ||||
|                                     .graph | ||||
|                                     .add_edge(*previous_node, *current_node, ()); | ||||
| 
 | ||||
|                                         if chained == Chain::YesIgnoreDeferred { | ||||
|                                             self.no_sync_edges | ||||
|                                                 .insert((*previous_node, *current_node)); | ||||
|                                 if ignore_deferred { | ||||
|                                     self.no_sync_edges.insert((*previous_node, *current_node)); | ||||
|                                 } | ||||
|                             } | ||||
|                         } | ||||
|                     } | ||||
|                         } | ||||
| 
 | ||||
|                     if collect_nodes { | ||||
|                             nodes_in_scope.append(&mut previous_result.nodes); | ||||
|                         nodes.append(&mut previous_result.nodes); | ||||
|                     } | ||||
| 
 | ||||
|                     previous_result = current_result; | ||||
|                 } | ||||
| 
 | ||||
|                     // ensure the last config's nodes are added
 | ||||
|                 if collect_nodes { | ||||
|                         nodes_in_scope.append(&mut previous_result.nodes); | ||||
|                     } | ||||
|                 } else { | ||||
|                     for config in config_iter { | ||||
|                         let result = self.process_configs(config, collect_nodes); | ||||
|                         densely_chained = densely_chained && result.densely_chained; | ||||
|                         if collect_nodes { | ||||
|                             nodes_in_scope.extend(result.nodes); | ||||
|                         } | ||||
|                     } | ||||
| 
 | ||||
|                     // an "unchained" SystemConfig is only densely chained if it has exactly one densely chained entry
 | ||||
|                     if more_than_one_entry { | ||||
|                         densely_chained = false; | ||||
|                     } | ||||
|                     nodes.append(&mut previous_result.nodes); | ||||
|                 } | ||||
| 
 | ||||
|                 ProcessConfigsResult { | ||||
|                     nodes: nodes_in_scope, | ||||
|                     nodes, | ||||
|                     densely_chained, | ||||
|                 } | ||||
|             } | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jonathan
						Jonathan