You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							121 lines
						
					
					
						
							4.2 KiB
						
					
					
				
			
		
		
		
			
			
			
				
					
				
				
					
				
			
		
		
	
	
							121 lines
						
					
					
						
							4.2 KiB
						
					
					
				| import sys | |
| import os | |
| import json | |
| import pathlib | |
| import argparse | |
| import subprocess | |
| 
 | |
| import numpy | |
| import pandas | |
| 
 | |
| from combine_profiles import combine_profiles | |
| 
 | |
| 
 | |
| def get_fixture_dir(): | |
|     return (pathlib.Path(__file__).parents[1] / "fixtures").resolve() | |
| 
 | |
| 
 | |
| def sim_exe_name(): | |
|     return "rigid_ipc_sim" | |
| 
 | |
| 
 | |
| def find_sim_exe(): | |
|     for build_dir in (pathlib.Path("."), pathlib.Path(__file__).parents[1] / "build"): | |
|         for sub_dir in "", "release", "debug": | |
|             sim_exe = build_dir / sub_dir / sim_exe_name() | |
|             if sim_exe.is_file(): | |
|                 return sim_exe.resolve() | |
|     return None | |
| 
 | |
| 
 | |
| def create_parser(): | |
|     parser = argparse.ArgumentParser( | |
|         description="Run all scenes and save a CSV of the results.") | |
|     parser.add_argument( | |
|         "--sim-exe", metavar=f"path/to/{sim_exe_name()}", type=pathlib.Path, | |
|         default=find_sim_exe(), help="path to simulation executable") | |
|     parser.add_argument( | |
|         "-i", "--input", metavar="path/to/input", type=pathlib.Path, | |
|         dest="input", default=None, help="path to input json(s)", nargs="+") | |
|     parser.add_argument( | |
|         "-o", "--output", metavar="path/to/multithreading-profile.csv", | |
|         type=pathlib.Path, dest="output", | |
|         default=pathlib.Path("multithreading-profile.csv"), | |
|         help="path to output CSV") | |
|     parser.add_argument( | |
|         "--loglevel", default=3, type=int, choices=range(7), | |
|         help="set log level 0=trace, 1=debug, 2=info, 3=warn, 4=error, 5=critical, 6=off") | |
|     return parser | |
| 
 | |
| 
 | |
| def parse_arguments(): | |
|     parser = create_parser() | |
|     args = parser.parse_args() | |
|     if args.sim_exe is None: | |
|         parser.exit(1, "Simulation executable is required!\n") | |
|     if args.input is None: | |
|         args.input = [ | |
|             get_fixture_dir() / "3D/chain/chain-line/length=0051.json", | |
|             get_fixture_dir() / "3D/chain/chain-line/length=0091.json", | |
|             get_fixture_dir() / "3D/chain/chain-line/sub4/length=0023.json", | |
|             get_fixture_dir() / "3D/chain/chain-line/sub4/length=0053.json"] | |
|     input_jsons = [] | |
|     for input_file in args.input: | |
|         if input_file.is_file() and input_file.suffix == ".json": | |
|             input_jsons.append(input_file.resolve()) | |
|         elif input_file.is_dir(): | |
|             input_jsons.extend(list(input_file.glob('**/*.json'))) | |
|     args.input = input_jsons | |
|     return args | |
| 
 | |
| 
 | |
| def append_stem(p, stem_suffix): | |
|     # return p.with_stem(p.stem + stem_suffix) | |
|     return p.parent / (p.stem + stem_suffix + p.suffix) | |
| 
 | |
| 
 | |
| def main(): | |
|     args = parse_arguments() | |
|     fixture_dir = get_fixture_dir() | |
| 
 | |
|     scalability_profiles = [] | |
| 
 | |
|     for thread_count in [1, 2, 4, 8, -1]: | |
|         thread_count_str = "unlimited" if thread_count < 0 else thread_count | |
|         for scene in args.input: | |
|             # if thread_count == 1: | |
|             #     continue | |
| 
 | |
|             print(f"Running {scene}") | |
|             try: | |
|                 scene_name = scene.resolve().relative_to(fixture_dir) | |
|                 scene_name = str(scene_name.parent / scene_name.stem) | |
|             except ValueError: | |
|                 scene_name = scene.stem | |
| 
 | |
|             sim_output_dir = (pathlib.Path( | |
|                 f"output-{thread_count_str}threads") / scene_name) | |
|             subprocess.run([str(args.sim_exe), "--ngui", str(scene.resolve()), | |
|                             str(sim_output_dir), | |
|                             "--loglevel", str(args.loglevel), | |
|                             "--nthreads", str(thread_count) | |
|                             ]) | |
|         combined_profile_df = combine_profiles( | |
|             args.input, absolute_time=True, | |
|             base_output=f"output-{thread_count_str}threads") | |
|         average_percent_time = ( | |
|             (combined_profile_df / combined_profile_df.loc["run_simulation"]) | |
|             .mean(axis=1).map(lambda x: f"{x:%}")) | |
|         if scalability_profiles: | |
|             combined_profile_df = scalability_profiles[0] / combined_profile_df | |
|         combined_profile_df["average_percent_time"] = average_percent_time | |
| 
 | |
|         scalability_profiles.append(combined_profile_df) | |
| 
 | |
|         output_fname = append_stem(args.output, f"-{thread_count_str}-threads") | |
|         combined_profile_df.to_csv(output_fname) | |
|         print(f"Results written to {output_fname}") | |
| 
 | |
| 
 | |
| if __name__ == "__main__": | |
|     main()
 | |
| 
 |