103 Extract and display hardcoded split parameters from a tree for Peano's Hardcoded load balancer.
106 peano_tree: Tree object with applied splits
107 title: Title to display before the parameters
109 if peano_tree._subtree_count <= 1:
110 print(
"No splits to extract - tree has only one subtree")
114 splitting_trees, cell_counts, subtrees, bottom_up_flags = split_strategy.extract_split_instructions(peano_tree)
117 print(
"-" * len(title))
118 print(f
"Total subtrees: {peano_tree._subtree_count}")
119 print(f
"Total leaf nodes: {int(peano_tree._leaf_count)}")
123 print(
"Hardcoded Constructor Parameters:")
124 print(f
" splittingTrees = {{{', '.join(map(str, splitting_trees))}}}")
125 print(f
" numberOfCells = {{{', '.join(map(str, cell_counts))}}}")
126 print(f
" subTrees = {{{', '.join(map(str, subtrees))}}}")
130 print(
"Individual Split Operations:")
131 for i
in range(len(subtrees)):
132 mode =
"bottom-up" if bottom_up_flags[i]
else "top-down"
133 print(f
" split {i}: tree {splitting_trees[i]} → tree {subtrees[i]}; {cell_counts[i]} cells; {mode}")
138 parser = argparse.ArgumentParser(description=
'Offline Tree Decomposition for Load Balancing')
139 parser.add_argument(
"-f",
"--file", dest=
"file_path", type=str, help=
"Path to input grid patch file (e.g., Input/example2)" )
140 parser.add_argument(
"-y",
"--yaml", dest=
"yaml_path", type=str, help=
"Path to input YAML file created by generate_tree_yaml()" )
141 parser.add_argument(
"-p",
"--plot", dest=
"plot_flag", action=
"store_true", default=
False, help=
"Generate and save visualization plots of the tree structure" )
142 parser.add_argument(
"-d",
"--dimensions", dest=
"grid_dimensions", type=int, help=
"Spatial dimensions of the grid (2 for 2D, 3 for 3D) - auto-detected from YAML if not specified" )
143 parser.add_argument(
"-l",
"--max-level", dest=
"max_level", type=int, default=0, help=
"Maximum refinement level for artificial regular grid generation" )
144 parser.add_argument(
"-s",
"--subtrees", dest=
"subtrees", type=int, help=
"Total number of subtrees to create via splitting")
145 parser.add_argument(
"-o",
"--output", dest=
"output_yaml", type=str, default=
"output.yaml", help=
"Output YAML file path for storing split results and tree structure")
146 parser.add_argument(
"-t",
"--traversal", dest=
"traversal_mode", type=str, choices=[
"bfs",
"bfs_finest_first",
"dfs"], default=
"bfs_finest_first", help=
"Stage I traversal mode for split_tree(): 'bfs', 'bfs_finest_first' (default) or 'dfs'")
147 parser.add_argument(
"--no-topology-update", dest=
"topology_update", action=
"store_false", default=
True, help=
"Disable topology preservation (skip non-leaf subtree propagation) during split_tree()")
149 args = parser.parse_args()
153 if args.yaml_path !=
None:
154 name =
"YAML-"+os.path.basename(args.yaml_path)
155 filename = args.yaml_path
158 if args.grid_dimensions
is None:
159 args.grid_dimensions = tree._dimension
160 elif args.file_path !=
None:
161 if args.grid_dimensions
is None:
162 print(
"Error: -d/--dimensions is required when using grid patch files")
164 name =
"Files-"+args.file_path
165 filename = args.file_path
166 tree =
GridPatchFileReader(name=name, file_path=args.file_path, dimensions=args.grid_dimensions)
167 elif args.max_level > 0:
168 if args.grid_dimensions
is None:
169 print(
"Error: -d/--dimensions is required when generating regular grids")
171 name =
"Regular-Grid-Generator"
172 filename=
"TreeStructure"
173 tree =
RegularGridGenerator(name=name, max_level=args.max_level, dimensions=args.grid_dimensions)
175 print(
"No input specified. Use one of: -f (grid files), -y (YAML file), or -l (regular grid generation)")
180 print(
"Original tree:")
185 print(
"GENERATING ORIGINAL TREE YAML")
190 original_yaml_filename = f
"Files-{os.path.basename(args.file_path)}_original.yaml"
192 original_yaml_filename = f
"TreeStructure_l{args.max_level}_original.yaml"
195 original_yaml_filename = original_yaml_filename.replace(
'/',
'_').replace(
'\\',
'_')
197 split_strategy.generate_tree_yaml(tree, original_yaml_filename)
200 if tree._subtree_count > 1:
202 print(
"HARDCODED SPLIT PARAMETERS FOR ORIGINAL TREE")
208 print(
"SKIPPING ORIGINAL TREE HARDCODED SPLIT PARAMETERS")
210 print(
"Original tree has only one subtree - no split parameters to extract")
213 viz_start_time = time.time()
217 base_name = f
"Files-{os.path.basename(args.file_path)}"
218 original_plot_filename = f
"{base_name}_original"
220 base_name = f
"YAML-{os.path.splitext(os.path.basename(args.yaml_path))[0]}"
221 original_plot_filename = f
"{base_name}_original"
223 base_name =
"TreeStructure"
224 original_plot_filename = f
"{base_name}_l{args.max_level}_original"
227 original_plot_filename = original_plot_filename.replace(
'/',
'_').replace(
'\\',
'_')
230 print(
"GENERATING ORIGINAL TREE VISUALIZATION")
233 TreeVisualizer(tree, args.grid_dimensions, original_plot_filename)
234 print(f
"Original tree visualization saved as {original_plot_filename}.pdf and {original_plot_filename}.png")
236 viz_end_time = time.time()
239 split_start_time = 0.0
243 if args.subtrees
is not None:
245 print(
"INITIALLY RESETTING TREE TO SINGLE SUBTREE")
249 tree = split_strategy.reset_tree_to_single_subtree(tree)
252 print(
"APPLYING FINEST LEVEL SPLITTING")
255 split_start_time = time.time()
258 number_of_subtrees = args.subtrees
259 decomposition = equidistant_splitting(
265 split_strategy.split_tree(
268 traversal=args.traversal_mode,
269 enable_propagate_bottom_up=args.topology_update,
272 split_end_time = time.time()
274 print(f
"Splitting Time Cost: {(split_end_time - split_start_time):.4f} seconds")
276 print(
"\nTree after splitting:")
281 print(
"GENERATING SPLIT RESULTS YAML")
286 split_yaml_filename = f
"Files-{os.path.basename(args.file_path)}_s{args.subtrees}_split.yaml"
288 base_name = os.path.splitext(os.path.basename(args.yaml_path))[0]
289 split_yaml_filename = f
"YAML-{base_name}_s{args.subtrees}_split.yaml"
291 split_yaml_filename = f
"TreeStructure_l{args.max_level}_s{args.subtrees}_split.yaml"
294 split_yaml_filename = split_yaml_filename.replace(
'/',
'_').replace(
'\\',
'_')
297 split_strategy.generate_tree_yaml(tree, split_yaml_filename)
298 print(f
"Split tree YAML saved as {split_yaml_filename}")
302 print(
"HARDCODED SPLIT PARAMETERS FOR SPLIT TREE")
310 base_name = f
"Files-{os.path.basename(args.file_path)}"
311 split_plot_filename = f
"{base_name}_s{args.subtrees}"
313 base_name = f
"YAML-{os.path.splitext(os.path.basename(args.yaml_path))[0]}"
314 split_plot_filename = f
"{base_name}_s{args.subtrees}"
316 base_name =
"TreeStructure"
317 split_plot_filename = f
"{base_name}_l{args.max_level}_s{args.subtrees}"
319 split_plot_filename = split_plot_filename.replace(
'/',
'_').replace(
'\\',
'_')
322 print(
"GENERATING SPLIT TREE VISUALIZATION")
326 print(f
"Split tree visualization saved as {split_plot_filename}.pdf and {split_plot_filename}.png")
333 print(f
"Input Time Cost: {(time2-time1):.4f} seconds")
335 print(f
"Visualization Time Cost: {(viz_end_time-viz_start_time):.4f} seconds")
336 if args.subtrees
is not None:
337 print(f
"Splitting Time Cost: {(split_end_time-split_start_time):.4f} seconds")
338 print(f
"Total Time Cost: {(time3-time1):.4f} seconds")