@@ -71,8 +71,6 @@ class IsomorphicSubgraphScheduler {
7171
7272 std::vector<vertex_idx_t <Graph_t>> compute_partition (const BspInstance<Graph_t>& instance) {
7373 OrbitGraphProcessor<Graph_t, Constr_Graph_t> orbit_processor (symmetry_);
74- orbit_processor.set_work_threshold (work_threshold_);
75- orbit_processor.setMergeDifferentNodeTypes (merge_different_node_types);
7674
7775 std::unique_ptr<HashComputer<vertex_idx_t <Graph_t>>> local_hasher;
7876 if (!hash_computer_) {
@@ -84,26 +82,37 @@ class IsomorphicSubgraphScheduler {
8482
8583 auto isomorphic_groups = orbit_processor.get_final_groups ();
8684
87- trim_subgraph_groups (isomorphic_groups, instance); // Apply trimming based on dynamic min_proc_type_count
85+ if (plot_dot_graphs_) {
86+ DotFileWriter writer;
87+ writer.write_colored_graph (" isomorphic_groups.dot" , instance.getComputationalDag (), orbit_processor.get_final_contraction_map ());
88+ writer.write_colored_graph (" orbits_colored.dot" , instance.getComputationalDag (), orbit_processor.get_contraction_map ());
89+ }
90+
91+ const unsigned min_proc_type_count = use_max_group_size_ ? max_group_size_ : instance.getArchitecture ().getMinProcessorTypeCount ();
92+ trim_subgraph_groups (isomorphic_groups, min_proc_type_count);
8893
8994 auto input = prepare_subgraph_scheduling_input (instance, isomorphic_groups);
9095
96+ if (plot_dot_graphs_) {
97+ DotFileWriter writer;
98+ writer.write_graph (" iso_groups_contracted.dot" , input.instance .getComputationalDag ());
99+ }
100+
91101 EftSubgraphScheduler<Constr_Graph_t> etf_scheduler;
92102 SubgraphSchedule subgraph_schedule = etf_scheduler.run (input.instance , input.multiplicities , input.required_proc_types );
93103
94104 std::vector<vertex_idx_t <Graph_t>> partition (instance.numberOfVertices (), 0 );
105+
95106 schedule_isomorphic_group (instance, isomorphic_groups, subgraph_schedule, partition);
96107
97108 if (plot_dot_graphs_) {
98109 DotFileWriter writer;
99- writer.write_colored_graph (" isomorphic_groups.dot" , instance.getComputationalDag (), orbit_processor.get_final_contraction_map ());
100- writer.write_colored_graph (" orbits_colored.dot" , instance.getComputationalDag (), orbit_processor.get_contraction_map ());
101- writer.write_graph (" iso_groups_contracted.dot" , input.instance .getComputationalDag ());
102110 writer.write_colored_graph (" graph_partition.dot" , instance.getComputationalDag (), partition);
103111 Constr_Graph_t corase_graph;
104112 coarser_util::construct_coarse_dag (instance.getComputationalDag (), corase_graph, partition);
105113 writer.write_graph (" block_graph.dot" , corase_graph);
106114 }
115+
107116 return partition;
108117 }
109118
@@ -117,125 +126,35 @@ class IsomorphicSubgraphScheduler {
117126 };
118127
119128 void trim_subgraph_groups (std::vector<typename OrbitGraphProcessor<Graph_t, Constr_Graph_t>::Group>& isomorphic_groups,
120- const BspInstance<Graph_t>& instance) {
121- if constexpr (verbose) {
122- std::cout << " \n --- Trimming Isomorphic Subgraph Groups ---" << std::endl;
123- }
124- size_t group_idx_debug = 0 ;
125- for (auto & group : isomorphic_groups) {
126- const unsigned group_size = static_cast <unsigned >(group.size ());
127- if (group_size <= 1 )
128- continue ;
129-
130- unsigned effective_min_proc_type_count = 0 ;
129+ const unsigned min_proc_type_count) {
130+ if (min_proc_type_count <= 1 ) return ;
131131
132- if (use_max_group_size_) {
133- if constexpr (verbose) {
134- std::cout << " Group " << group_idx_debug << " (size " << group_size << " ): Using fixed max_group_size_ = " << max_group_size_ << " for trimming." << std::endl;
135- }
136- effective_min_proc_type_count = max_group_size_;
137- } else {
138- // Determine if the group consists of a single node type
139- bool is_single_type_group = true ;
140- v_type_t <Graph_t> common_node_type = 0 ;
141-
142- if constexpr (has_typed_vertices_v<Graph_t>) {
143- if (!group.subgraphs .empty () && !group.subgraphs [0 ].empty ()) {
144- common_node_type = instance.getComputationalDag ().vertex_type (group.subgraphs [0 ][0 ]);
145- const auto & rep_subgraph = group.subgraphs [0 ];
146- for (const auto & vertex : rep_subgraph) {
147- if (instance.getComputationalDag ().vertex_type (vertex) != common_node_type) {
148- is_single_type_group = false ;
149- break ;
150- }
151- }
152- } else {
153- is_single_type_group = false ;
154- }
155- } else {
156- is_single_type_group = false ;
157- }
158-
159- if (is_single_type_group) {
160- // Dynamically determine min_proc_type_count based on compatible processors for this type
161- unsigned min_compatible_processors = std::numeric_limits<unsigned >::max ();
162- const auto & proc_type_counts = instance.getArchitecture ().getProcessorTypeCount ();
163-
164- bool found_compatible_processor = false ;
165- for (unsigned proc_type_idx = 0 ; proc_type_idx < proc_type_counts.size (); ++proc_type_idx) {
166- if (instance.isCompatibleType (common_node_type, proc_type_idx)) {
167- min_compatible_processors = std::min (min_compatible_processors, proc_type_counts[proc_type_idx]);
168- found_compatible_processor = true ;
169- }
170- }
171- if (found_compatible_processor) {
172- if constexpr (verbose) {
173- std::cout << " Group " << group_idx_debug << " (size " << group_size << " ): Single node type (" << common_node_type
174- << " ). Min compatible processors: " << min_compatible_processors << " ." << std::endl;
175- }
176- effective_min_proc_type_count = min_compatible_processors;
177- } else {
178- if constexpr (verbose) {
179- std::cout << " Group " << group_idx_debug << " (size " << group_size << " ): Single node type (" << common_node_type
180- << " ) but no compatible processors found. Disabling trimming." << std::endl;
181- }
182- // If no compatible processors found for this type, effectively disable trimming for this group.
183- effective_min_proc_type_count = 1 ;
184- }
185- } else {
186- // Fallback to a default min_proc_type_count if not a single-type group or no typed vertices.
187- effective_min_proc_type_count = instance.getArchitecture ().getMinProcessorTypeCount ();
188- if constexpr (verbose) {
189- std::cout << " Group " << group_idx_debug << " (size " << group_size << " ): Multi-type or untyped group. Using default min_proc_type_count: " << effective_min_proc_type_count << " ." << std::endl;
190- }
191- }
192- }
193-
194- // Ensure effective_min_proc_type_count is at least 1 for valid GCD calculation.
195- if (effective_min_proc_type_count == 0 ) {
196- effective_min_proc_type_count = 1 ;
197- }
198-
199- // If effective_min_proc_type_count is 1, no trimming is needed as gcd(X, 1) = 1.
200- if (effective_min_proc_type_count <= 1 ) {
132+ for (auto & group : isomorphic_groups) {
133+ const unsigned group_size = static_cast <unsigned >(group.subgraphs .size ());
134+ if (group_size == 0 )
201135 continue ;
202- }
203-
204- const unsigned gcd = std::gcd (group_size, effective_min_proc_type_count);
136+ const unsigned gcd = std::gcd (group_size, min_proc_type_count);
205137
206138 if (gcd < group_size) {
207- if constexpr (verbose) {
208- std::cout << " -> Trimming group " << group_idx_debug << " . GCD(" << group_size << " , " << effective_min_proc_type_count
209- << " ) = " << gcd << " . Merging " << group_size / gcd << " subgraphs at a time." << std::endl;
210- }
211-
212139 const unsigned merge_size = group_size / gcd;
213140 std::vector<std::vector<vertex_idx_t <Graph_t>>> new_subgraphs;
214141 new_subgraphs.reserve (gcd);
215142
216143 size_t original_sg_cursor = 0 ;
217144
218145 for (unsigned j = 0 ; j < gcd; ++j) {
219- std::vector<vertex_idx_t <Graph_t>> merged_sg_vertices;
220- // Estimate capacity for efficiency. Assuming subgraphs have similar sizes.
221- if (!group.subgraphs .empty ()) {
222- merged_sg_vertices.reserve (group.subgraphs [0 ].size () * merge_size);
223- }
146+ std::vector<vertex_idx_t <Graph_t>> merged_sg_vertices = group.subgraphs [original_sg_cursor];
147+ original_sg_cursor++;
224148
225- for (unsigned k = 0 ; k < merge_size; ++k) {
149+ for (unsigned k = 1 ; k < merge_size; ++k) {
226150 const auto & sg_to_merge_vertices = group.subgraphs [original_sg_cursor];
227151 original_sg_cursor++;
228152 merged_sg_vertices.insert (merged_sg_vertices.end (), sg_to_merge_vertices.begin (), sg_to_merge_vertices.end ());
229153 }
230154 new_subgraphs.push_back (std::move (merged_sg_vertices));
231155 }
232156 group.subgraphs = std::move (new_subgraphs);
233- } else {
234- if constexpr (verbose) {
235- std::cout << " -> No trim needed for group " << group_idx_debug << " ." << std::endl;
236- }
237157 }
238- group_idx_debug++;
239158 }
240159 }
241160
0 commit comments