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 |         &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.
 |     /// 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`].
 |     /// `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, |         collect_nodes: bool, | ||||||
|     ) -> ProcessConfigsResult { |     ) -> ProcessConfigsResult { | ||||||
|         match configs { |         match configs { | ||||||
|             NodeConfigs::NodeConfig(config) => { |             NodeConfigs::NodeConfig(config) => self.process_config(config, collect_nodes), | ||||||
|                 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::Configs { |             NodeConfigs::Configs { | ||||||
|                 mut configs, |                 mut configs, | ||||||
|                 collective_conditions, |                 collective_conditions, | ||||||
|                 chained, |                 chained, | ||||||
|             } => { |             } => { | ||||||
|                 let more_than_one_entry = configs.len() > 1; |                 self.apply_collective_conditions(&mut configs, collective_conditions); | ||||||
|                 if !collective_conditions.is_empty() { | 
 | ||||||
|                     if more_than_one_entry { |                 let ignore_deferred = matches!(chained, Chain::YesIgnoreDeferred); | ||||||
|                         let set = self.create_anonymous_set(); |                 let chained = matches!(chained, Chain::Yes | Chain::YesIgnoreDeferred); | ||||||
|                         for config in &mut configs { | 
 | ||||||
|                             config.in_set_inner(set.intern()); |                 // Densely chained if
 | ||||||
|                         } |                 // * chained and all configs in the chain are densely chained, or
 | ||||||
|                         let mut set_config = SystemSetConfig::new(set.intern()); |                 // * unchained with a single densely chained config
 | ||||||
|                         set_config.conditions.extend(collective_conditions); |                 let mut densely_chained = chained || configs.len() == 1; | ||||||
|                         self.configure_set_inner(set_config).unwrap(); |                 let mut configs = configs.into_iter(); | ||||||
|                     } else { |                 let mut nodes = Vec::new(); | ||||||
|                         for condition in collective_conditions { | 
 | ||||||
|                             configs[0].run_if_dyn(condition); |                 let Some(first) = configs.next() else { | ||||||
|                         } |                     return ProcessConfigsResult { | ||||||
|                     } |                         nodes: Vec::new(), | ||||||
|                 } |                         densely_chained, | ||||||
|                 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 { |  | ||||||
|                         return ProcessConfigsResult { |  | ||||||
|                             nodes: Vec::new(), |  | ||||||
|                             densely_chained: true, |  | ||||||
|                         }; |  | ||||||
|                     }; |                     }; | ||||||
|                     let mut previous_result = self.process_configs(prev, true); |                 }; | ||||||
|                     densely_chained = previous_result.densely_chained; |                 let mut previous_result = self.process_configs(first, collect_nodes || chained); | ||||||
|                     for current in config_iter { |                 densely_chained &= previous_result.densely_chained; | ||||||
|                         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, |  | ||||||
|                                     (), |  | ||||||
|                                 ); |  | ||||||
| 
 | 
 | ||||||
|                                 if chained == Chain::YesIgnoreDeferred { |                 for current in configs { | ||||||
|                                     self.no_sync_edges |                     let current_result = self.process_configs(current, collect_nodes || chained); | ||||||
|                                         .insert((*last_in_prev, *first_in_current)); |                     densely_chained &= current_result.densely_chained; | ||||||
|                                 } |  | ||||||
|                             } |  | ||||||
|                             // 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, |  | ||||||
|                                         (), |  | ||||||
|                                     ); |  | ||||||
| 
 | 
 | ||||||
|                                     if chained == Chain::YesIgnoreDeferred { |                     if chained { | ||||||
|                                         self.no_sync_edges.insert((*last_in_prev, *current_node)); |                         // 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 { | ||||||
|                             // The current list is currently "densely" chained, so we can simplify the graph by
 |                             ¤t_result.nodes | ||||||
|                             // only chaining every item in the previous list to the first item in the current list
 |                         }; | ||||||
|                             (false, true) => { |                         // if the previous result was densely chained, we only need to chain the last node
 | ||||||
|                                 let first_in_current = current_result.nodes.first().unwrap(); |                         let previous_nodes = if previous_result.densely_chained { | ||||||
|                                 for previous_node in &previous_result.nodes { |                             &previous_result.nodes[previous_result.nodes.len() - 1..] | ||||||
|                                     self.dependency.graph.add_edge( |                         } else { | ||||||
|                                         *previous_node, |                             &previous_result.nodes | ||||||
|                                         *first_in_current, |                         }; | ||||||
|                                         (), |  | ||||||
|                                     ); |  | ||||||
| 
 | 
 | ||||||
|                                     if chained == Chain::YesIgnoreDeferred { |                         for previous_node in previous_nodes { | ||||||
|                                         self.no_sync_edges |                             for current_node in current_nodes { | ||||||
|                                             .insert((*previous_node, *first_in_current)); |                                 self.dependency | ||||||
|                                     } |                                     .graph | ||||||
|                                 } |                                     .add_edge(*previous_node, *current_node, ()); | ||||||
|                             } |  | ||||||
|                             // 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, |  | ||||||
|                                             (), |  | ||||||
|                                         ); |  | ||||||
| 
 | 
 | ||||||
|                                         if chained == Chain::YesIgnoreDeferred { |                                 if ignore_deferred { | ||||||
|                                             self.no_sync_edges |                                     self.no_sync_edges.insert((*previous_node, *current_node)); | ||||||
|                                                 .insert((*previous_node, *current_node)); |  | ||||||
|                                         } |  | ||||||
|                                     } |  | ||||||
|                                 } |                                 } | ||||||
|                             } |                             } | ||||||
|                         } |                         } | ||||||
| 
 |  | ||||||
|                         if collect_nodes { |  | ||||||
|                             nodes_in_scope.append(&mut previous_result.nodes); |  | ||||||
|                         } |  | ||||||
| 
 |  | ||||||
|                         previous_result = current_result; |  | ||||||
|                     } |                     } | ||||||
| 
 |  | ||||||
|                     // ensure the last config's nodes are added
 |  | ||||||
|                     if collect_nodes { |                     if collect_nodes { | ||||||
|                         nodes_in_scope.append(&mut previous_result.nodes); |                         nodes.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
 |                     previous_result = current_result; | ||||||
|                     if more_than_one_entry { |                 } | ||||||
|                         densely_chained = false; |                 if collect_nodes { | ||||||
|                     } |                     nodes.append(&mut previous_result.nodes); | ||||||
|                 } |                 } | ||||||
| 
 | 
 | ||||||
|                 ProcessConfigsResult { |                 ProcessConfigsResult { | ||||||
|                     nodes: nodes_in_scope, |                     nodes, | ||||||
|                     densely_chained, |                     densely_chained, | ||||||
|                 } |                 } | ||||||
|             } |             } | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Jonathan
						Jonathan