diff --git a/README.md b/README.md index 2db235b..cb5b6ec 100644 --- a/README.md +++ b/README.md @@ -26,6 +26,7 @@ If your project requires several additional dependencies you should document thi - [**temporal_memory**](./temporal_memory): A first implementation of the HTM algorithm for recognizing 3D objects. Includes data preprocessing and SDR generation for 3D locations. Note: This code was written when the Monty framework was not well established yet. - [**touch_sensor**](./touch_sensor): The first implementation of a sensor moving along the surface of an object. This is now integrated in the Monty framework and called "surface agent". - [**very_first_experiments**](./very_first_experiments): A couple of notebooks visualizing first experiments of working with sensorimotor data collected in habitat and building and extending graphs using this data. +- [**dmc_configs**](./dmc_configs): A collection of configs for experiments found in the "Demonstrating Monty's Capabilities" paper. ## Contributing This repository is not meant for external contributors. It is just a place where the TBP team keeps its project files. If you are on the TBP team and start working on a new project, please remember to always add a README in your project folder and a short description in the "Content" section here. diff --git a/analysis_results/flop_analysis_20250106_112121.csv b/analysis_results/flop_analysis_20250106_112121.csv new file mode 100644 index 0000000..d66d2a0 --- /dev/null +++ b/analysis_results/flop_analysis_20250106_112121.csv @@ -0,0 +1,1101 @@ +filename,operation_type,module,function,method_context,line,column,symbol +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/actions.py,arithmetic_ops,arithmetic,multiplication,_move_along_diagonal,54,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/agents.py,arithmetic_ops,arithmetic,addition,__init__,288,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/agents.py,arithmetic_ops,arithmetic,addition,__init__,385,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/agents.py,import,numpy,np,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,division,,39,29,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,numpy_ops,np,random.default_rng,__init__,104,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,division,__init__,133,24,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,division,__init__,143,31,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,subtraction,check_viewpoint_collision,363,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,subtraction,check_viewpoint_collision,364,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,division,check_viewpoint_collision,366,29,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,numpy_ops,np,linalg.norm,find_non_colliding_positions,404,21, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,addition,find_non_colliding_positions,408,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,arithmetic_ops,arithmetic,multiplication,find_non_colliding_positions,408,39,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/habitat/simulator.py,import,numpy,np,,22,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/config.py,arithmetic_ops,arithmetic,division,,180,38,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/config.py,arithmetic_ops,arithmetic,division,,183,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,60,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,division,__post_init__,60,29,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,addition,__post_init__,60,44,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,division,__post_init__,60,49,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,61,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,division,__post_init__,61,29,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,addition,__post_init__,61,45,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,division,__post_init__,61,50,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,63,13,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,power,__post_init__,63,17,** +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,63,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,63,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,power,__post_init__,63,31,** +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,power,__post_init__,63,38,** +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,63,39,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,power,__post_init__,63,55,** +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,63,56,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,subtraction,__post_init__,64,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,division,__post_init__,64,21,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,arithmetic_ops,arithmetic,multiplication,__post_init__,64,21,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/simulators/tacto/sensors.py,import,numpy,np,,19,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run.py,arithmetic_ops,arithmetic,multiplication,print_config,39,10,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run.py,arithmetic_ops,arithmetic,multiplication,print_config,41,10,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run.py,arithmetic_ops,arithmetic,subtraction,main,114,53,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,95,47,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,96,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,99,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,102,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,104,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,106,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,108,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,multiplication,get_overall_stats,110,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,subtraction,run_episodes_parallel,319,30,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,subtraction,run_episodes_parallel,349,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,subtraction,run_episodes_parallel,356,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,subtraction,run_episodes_parallel,386,50,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,numpy_ops,np,random.RandomState,generate_parallel_train_configs,415,18, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,numpy_ops,np,random.RandomState,generate_parallel_eval_configs,451,18, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,arithmetic_ops,arithmetic,addition,generate_parallel_eval_configs,467,52,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/run_parallel.py,import,numpy,np,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,multiplication,,48,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,,48,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,multiplication,,65,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,,65,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,modulo,__call__,520,27,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,modulo,__call__,526,42,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,modulo,__call__,528,36,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,modulo,__call__,529,30,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,682,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,693,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,693,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,699,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,699,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,699,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,699,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,705,45,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_train_dataloader,706,43,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,737,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,748,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,748,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,755,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,755,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,755,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,755,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,subtraction,get_omniglot_eval_dataloader,758,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,760,31,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,763,45,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,arithmetic_ops,arithmetic,addition,get_omniglot_eval_dataloader,764,43,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,import,numpy,np,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/make_dataset_configs.py,import,scipy.spatial.transform,Rotation,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,division,,660,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,660,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,660,63,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,division,,788,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,788,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,788,63,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,division,,978,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,978,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,978,63,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,division,,1003,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,1003,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,multiplication,,1003,63,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,modulo,get_possible_3d_rotations,1176,17,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,arithmetic_ops,arithmetic,addition,get_possible_3d_rotations,1176,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,import,numpy,np,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/config_utils/config_args.py,import,scipy.spatial.transform,Rotation,,18,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/wandb_handlers.py,arithmetic_ops,arithmetic,subtraction,report_episode,128,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/wandb_handlers.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/monty_handlers.py,arithmetic_ops,arithmetic,addition,report_episode,87,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,update_overall_stats,261,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,315,39,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,316,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,get_formatted_overall_stats,316,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,320,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,321,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,324,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,325,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,get_formatted_overall_stats,325,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,329,43,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,330,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,333,44,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,334,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,337,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,338,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,341,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,342,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,345,54,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,346,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,get_formatted_overall_stats,346,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,352,46,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,353,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,get_formatted_overall_stats,353,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,354,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,357,47,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,358,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,358,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,361,47,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,362,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,get_formatted_overall_stats,362,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,363,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,366,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,367,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,368,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,371,47,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,372,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,multiplication,get_formatted_overall_stats,372,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,division,get_formatted_overall_stats,382,32,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,update_episode_data,479,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,arithmetic_ops,arithmetic,addition,update_episode_data,553,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,sklearn_ops,sklearn,LabelEncoder,__init__,149,35, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/loggers/graph_matching_loggers.py,import,sklearn.preprocessing,LabelEncoder,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,create_semantic_mapping,285,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,create_semantic_mapping,289,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,modulo,cycle_object,298,22,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,cycle_object,298,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,__init__,801,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,__init__,801,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,modulo,cycle_object,817,22,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,cycle_object,817,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,modulo,cycle_object,885,21,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,cycle_object,885,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,arithmetic_ops,arithmetic,addition,cycle_scene,964,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/embodied_data.py,import,numpy,np,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,division,__init__,64,49,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,__init__,71,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,modulo,step,108,35,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,step,114,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,modulo,get_state,133,29,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_state,138,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_state,142,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,reset,164,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,187,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,193,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,196,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,196,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,196,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,197,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,197,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,198,31,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,198,31,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_character_data,199,56,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,load_new_character_data,201,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,bitwise_and,load_new_character_data,204,12,& +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,bitwise_and,load_new_character_data,204,12,& +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,bitwise_and,load_new_character_data,204,12,& +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,load_new_character_data,210,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,get_image_patch,215,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,215,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_image_patch,216,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,216,25,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,get_image_patch,217,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,217,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_image_patch,218,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,218,25,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,division,__init__,251,49,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_state,362,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_state,366,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_scene_data,438,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_scene_data,441,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,load_new_scene_data,451,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,load_new_scene_data,451,45,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,division,get_3d_scene_point_cloud,508,44,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_3d_scene_point_cloud,512,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_move_area,572,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_move_area,572,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,get_move_area,575,34,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,get_move_area,576,34,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,get_image_patch,619,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,619,27,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_image_patch,620,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,620,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,subtraction,get_image_patch,621,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,621,27,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,get_image_patch,622,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,get_image_patch,622,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,multiplication,get_image_patch,628,13,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,multiplication,get_image_patch,634,13,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,multiplication,get_image_patch,638,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,multiplication,get_image_patch,639,15,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,division,__init__,661,49,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_scene_data,714,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,addition,load_new_scene_data,715,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,modulo,load_new_scene_data,719,15,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,load_new_scene_data,753,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,arithmetic_ops,arithmetic,floor_division,load_new_scene_data,753,39,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,scipy_ops,scipy,gaussian_filter,step,114,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,scipy_ops,scipy,gaussian_filter,reset,164,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,import,numpy,np,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environments/two_d_data.py,import,scipy.ndimage,gaussian_filter,,18,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/pretraining_experiments.py,arithmetic_ops,arithmetic,subtraction,run_episode,90,32,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/pretraining_experiments.py,import,numpy,np,,13,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/pretraining_experiments.py,import,scipy.spatial.transform,Rotation,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,addition,show_observations,127,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,floor_division,show_view_finder,164,21,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,multiplication,show_view_finder,164,21,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,floor_division,show_view_finder,164,49,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,multiplication,show_view_finder,164,49,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,division,show_view_finder,165,20,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,division,show_view_finder,166,20,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,addition,add_text,191,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,addition,add_text,191,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,addition,add_text,204,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,addition,add_text,204,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,arithmetic_ops,arithmetic,addition,add_text,212,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/object_recognition_experiments.py,import,numpy,np,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,numpy_ops,np,random.RandomState,unpack_experiment_args,88,19, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,arithmetic_ops,arithmetic,multiplication,init_model,134,62,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,arithmetic_ops,arithmetic,multiplication,init_model,135,62,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,arithmetic_ops,arithmetic,multiplication,init_model,136,72,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,arithmetic_ops,arithmetic,addition,init_model,159,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,arithmetic_ops,arithmetic,addition,init_loggers,337,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,arithmetic_ops,arithmetic,addition,init_loggers,337,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/experiments/monty_experiment.py,import,numpy,np,,17,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,floor_division,__init__,123,24,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,create_kernel,161,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,create_kernel,161,12,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,create_kernel,162,15,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,create_kernel,162,23,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,create_kernel,163,21,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,create_kernel,163,38,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,power,create_kernel,163,42,** +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,create_kernel,166,15,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,subtraction,conv2d,193,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,subtraction,conv2d,194,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,addition,conv2d,197,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,subtraction,conv2d,197,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,addition,conv2d,198,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,subtraction,conv2d,198,27,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,addition,conv2d,202,37,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,addition,conv2d,202,64,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,conv2d,204,37,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,conv2d,205,36,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,conv2d,206,47,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__init__,269,20,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__init__,272,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,__init__,276,28,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__init__,276,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,__init__,278,17,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,__init__,278,24,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,__init__,284,17,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__init__,284,17,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,__init__,290,21,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,division,__init__,291,26,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,numpy_ops,np,linalg.inv,__init__,297,30, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__call__,322,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__call__,335,29,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__call__,335,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,addition,__call__,343,53,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,multiplication,__call__,352,44,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,matrix_multiplication,__call__,356,42,@ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,addition,__call__,357,47,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,subtraction,get_on_surface_th,434,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,floor_division,get_on_surface_th,443,29,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,arithmetic_ops,arithmetic,subtraction,get_on_surface_th,449,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,scipy_ops,scipy,signal.convolve,__call__,145,31, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,import,numpy,np,,10,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/transforms.py,import,scipy,scipy,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,31,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,32,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,32,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,37,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,38,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,38,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,42,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,addition,do_PUT,42,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/server.py,arithmetic_ops,arithmetic,modulo,do_PUT,50,21,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/graph_utils.py,import,numpy,np,,10,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/environment_utils/habitat_utils.py,import,numpy,np,,10,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,floor_division,get_point_normal_naive,54,19,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,55,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_point_normal_naive,55,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,floor_division,get_point_normal_naive,57,18,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,61,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_point_normal_naive,61,38,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,61,49,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,62,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_point_normal_naive,62,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,62,51,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,64,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,65,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,66,19,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,66,31,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,67,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,67,30,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_naive,69,21,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_point_normal_naive,69,29, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_naive,70,23,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_point_normal_naive,70,33, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_naive,71,24,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_point_normal_naive,71,35, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_naive,72,23,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_point_normal_naive,72,33, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,77,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,83,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_naive,95,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_point_normal_naive,103,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,floor_division,get_point_normal_naive,115,22,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_naive,125,11,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_point_normal_naive,125,18, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.solve,get_point_normal_ordinary_least_squares,170,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_ordinary_least_squares,175,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_point_normal_ordinary_least_squares,175,42, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_point_normal_total_least_squares,233,17,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_total_least_squares,233,17,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_point_normal_total_least_squares,234,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_point_normal_total_least_squares,234,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_point_normal_total_least_squares,234,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.eig,get_point_normal_total_least_squares,238,31, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_curvature_at_point,328,13,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_curvature_at_point,328,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_curvature_at_point,341,13,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_curvature_at_point,341,17, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_curvature_at_point,345,13,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.solve,get_curvature_at_point,370,21, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_curvature_at_point,374,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,374,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,375,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_curvature_at_point,377,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,377,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,380,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,383,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.inv,get_curvature_at_point,387,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.eig,get_curvature_at_point,388,29, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_curvature_at_point,398,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,398,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,398,46,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_curvature_at_point,399,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,399,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_curvature_at_point,399,46,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_principal_curvatures,465,32,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_principal_curvatures,469,17, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_principal_curvatures,471,17, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.solve,get_principal_curvatures,517,21, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_principal_curvatures,522,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,522,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,523,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_principal_curvatures,525,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,525,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,528,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,531,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.inv,get_principal_curvatures,535,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.eig,get_principal_curvatures,536,29, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_principal_curvatures,546,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,546,22,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,546,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,get_principal_curvatures,547,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,547,22,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_principal_curvatures,547,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_center_neighbors,580,22,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_weight_matrix,612,12,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_weight_matrix,619,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_weight_matrix,619,8,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_weight_matrix,620,11,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_weight_matrix,620,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,division,get_weight_matrix,621,17,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,get_weight_matrix,621,47,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,power,get_weight_matrix,621,51,** +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,numpy_ops,np,linalg.norm,get_pixel_dist_to_center,641,21, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,get_pixel_dist_to_center,641,36,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,subtraction,point_pair_features,657,13,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,scale_clip,688,21,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,scale_clip,690,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,addition,log_sign,709,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,arithmetic_ops,arithmetic,multiplication,log_sign,710,18,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/sensor_processing.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,get_correct_k_n,33,10,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_correct_k_n,37,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,numpy_ops,np,linalg.norm,get_unique_paths,64,27, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_unique_paths,64,42,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,modulo,get_uniform_initial_possible_poses,117,16,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,get_uniform_initial_possible_poses,117,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,modulo,get_uniform_initial_possible_poses,118,16,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,get_uniform_initial_possible_poses,118,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,modulo,get_uniform_initial_possible_poses,119,16,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,get_uniform_initial_possible_poses,119,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,multiplication,add_pose_features_to_tolerances,171,56,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,division,get_scaled_evidences,236,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_scaled_evidences,237,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_scaled_evidences,238,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,multiplication,get_scaled_evidences,240,41,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_scaled_evidences,240,42,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,division,get_scaled_evidences,253,45,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_scaled_evidences,253,46,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_scaled_evidences,254,20,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,multiplication,get_scaled_evidences,257,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_scaled_evidences,257,46,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,get_custom_distances,289,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,numpy_ops,np,linalg.norm,get_custom_distances,297,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,get_custom_distances,306,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,multiplication,get_custom_distances,306,50,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,division,get_custom_distances,307,8,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,get_custom_distances,307,13,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,create_exponential_kernel,330,30,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,multiplication,create_exponential_kernel,331,20,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,detect_new_object_k_steps,398,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,process_delta_evidence_values,427,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,subtraction,find_step_on_new_object,461,15,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,arithmetic_ops,arithmetic,addition,find_step_on_new_object,461,15,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,import,numpy,np,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/graph_matching_utils.py,import,scipy.spatial.transform,Rotation,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,division,get_angle_beefed_up,113,11,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.norm,get_angle_beefed_up,113,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,division,get_angle_beefed_up,114,11,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.norm,get_angle_beefed_up,114,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,multiplication,get_angle_torch,156,55,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,check_orthonormal,160,36,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.inv,check_orthonormal,160,36, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,check_orthonormal,163,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.inv,check_orthonormal,163,29, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,check_orthonormal,166,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.norm,check_orthonormal,166,31, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,check_orthonormal,169,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.norm,check_orthonormal,169,28, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,align_orthonormal_vectors,201,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,numpy_ops,np,linalg.cond,non_singular_mat,247,7, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,division,non_singular_mat,247,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,multiplication,get_more_directions_in_plane,267,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,addition,get_more_directions_in_plane,267,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,addition,get_more_directions_in_plane,270,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,multiplication,get_more_directions_in_plane,270,18,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,multiplication,get_more_directions_in_plane,270,44,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,modulo,get_unique_rotations,298,33,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,modulo,get_unique_rotations,302,33,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,multiplication,pose_is_new,318,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,apply_rf_transform_to_points,421,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,subtraction,apply_rf_transform_to_points,425,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,addition,apply_rf_transform_to_points,426,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,arithmetic_ops,arithmetic,addition,apply_rf_transform_to_points,428,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,import,numpy,np,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/spatial_arithmetics.py,import,scipy.spatial.transform,Rotation,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/transform_utils.py,import,numpy,np,,10,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,numpy_ops,np,linalg.norm,already_in_list,73,8, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,subtraction,already_in_list,73,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,subtraction,already_in_list,108,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,subtraction,already_in_list,109,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,subtraction,already_in_list,109,32,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,subtraction,already_in_list,134,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,division,remove_close_points,202,50,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,multiplication,remove_close_points,202,61,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,multiplication,remove_close_points,202,72,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,addition,increment_sparse_tensor_by_count,240,17,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,addition,get_cubic_patches,292,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,addition,get_cubic_patches,293,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,addition,get_cubic_patches,294,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,addition,get_cubic_patches,299,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,bitwise_or,get_cubic_patches,301,18,| +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,floor_division,pose_vector_mean,334,26,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,division,pose_vector_mean,339,23,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,numpy_ops,np,linalg.norm,pose_vector_mean,339,35, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,floor_division,pose_vector_mean,341,33,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,division,pose_vector_mean,356,26,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,numpy_ops,np,linalg.norm,pose_vector_mean,356,37, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,division,pose_vector_mean,359,26,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,numpy_ops,np,linalg.norm,pose_vector_mean,359,37, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,multiplication,circular_mean,396,13,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,multiplication,circular_mean,396,13,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,multiplication,circular_mean,401,22,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,division,circular_mean,403,11,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,arithmetic_ops,arithmetic,multiplication,circular_mean,403,25,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/object_model_utils.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,plot_sample_animation,129,10,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_sample_animation,149,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_sample_animation,149,41,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_sample_animation,150,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_sample_animation,150,40,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_sample_animation,151,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_sample_animation,151,40,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,animate,164,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,164,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,212,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,212,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,212,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,plot_detection_animation,262,10,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,animate,309,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,309,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,317,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,division,animate,317,33,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,317,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,320,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,division,animate,320,33,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,320,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,division,mark_obs,342,21,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,mark_obs,344,33,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,division,mark_obs,352,15,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,mark_obs,352,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,mark_obs,352,48,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,mark_obs,356,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,mark_obs,357,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,mark_obs,358,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,mark_obs,359,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,get_model_id,376,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,get_action_name,414,34,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,format_ax,458,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,format_ax,459,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,format_ax,464,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,format_ax,465,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,format_ax,470,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,format_ax,471,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,format_ax,480,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,format_ax,480,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,get_search_positions,490,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,get_match_step,505,15,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_previous_path,531,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_previous_path,533,50,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_previous_path,534,50,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_previous_path,535,50,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,add_patch_outline_to_view_finder,544,9,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,add_patch_outline_to_view_finder,544,30,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,add_patch_outline_to_view_finder,545,9,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,add_patch_outline_to_view_finder,545,30,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_patch_outline_to_view_finder,546,9,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,add_patch_outline_to_view_finder,546,30,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_patch_outline_to_view_finder,547,9,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,add_patch_outline_to_view_finder,547,30,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_patch_outline_to_view_finder,551,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_patch_outline_to_view_finder,552,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_patch_outline_to_view_finder,553,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_patch_outline_to_view_finder,554,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,show_previous_possible_paths_with_nodes,560,36,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,update_text,583,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,update_text,583,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_feature_matching_animation,635,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_feature_matching_animation,648,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_feature_matching_animation,648,50,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_feature_matching_animation,655,37,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_feature_matching_animation,655,55,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,modulo,animate,664,29,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,floor_division,animate,665,15,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,division,animate,679,22,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,775,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_feature_matching_animation,791,56,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_normal,802,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_normal,802,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_normal,806,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_normal,806,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_normal,810,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_normal,810,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,show_one_step,865,14,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,show_one_step,877,62,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,show_one_step,878,64,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,show_one_step,880,61,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,show_one_step,909,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,numpy_ops,np,linalg.norm,show_one_step,913,29, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,show_one_step,914,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,modulo,show_one_step,923,24,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,show_one_step,923,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,division,show_one_step,924,47,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,animate,999,15,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,999,30,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,1000,77,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,animate,1057,15,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,1057,30,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,animate,1059,40,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,save_detection_stat_animation,1094,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,show_initial_hypotheses,1150,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,show_initial_hypotheses,1152,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1212,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1214,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1224,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_evidence_at_step,1224,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1225,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_evidence_at_step,1225,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1226,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_evidence_at_step,1226,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1234,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_evidence_at_step,1234,18,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_evidence_at_step,1289,19,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_evidence_at_step,1290,42,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_evidence_at_step,1298,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1304,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1331,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_at_step,1333,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_core_object,1427,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,derive_policy_details,1457,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,derive_policy_details,1465,51,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,derive_policy_details,1490,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_movement_step,1522,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_movement_step,1557,31,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_movement_step,1561,30,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_movement_step,1564,30,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_movement_step,1597,36,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,check_failed_jump,1655,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,check_failed_jump,1673,20,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,check_failed_jump,1684,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,check_failed_jump,1684,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,check_failed_jump,1688,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,check_failed_jump,1688,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,check_failed_jump,1692,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,check_failed_jump,1692,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_lm_processing,1736,37,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,add_lm_processing,1736,54,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_lm_processing,1737,37,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,add_lm_processing,1737,54,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_lm_processing,1738,37,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,add_lm_processing,1738,54,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_sensor_scatter,1768,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,add_sensor_scatter,1768,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_sensor_scatter,1769,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,add_sensor_scatter,1769,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,add_sensor_scatter,1770,32,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,add_sensor_scatter,1770,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_up_to_step,1793,26,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,subtraction,plot_animation,1814,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_animation,1819,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_animation,1819,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_animation,1819,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_animation,1819,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,visualize_plot,1830,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,visualize_plot,1832,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_learned_graph,1885,8,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,numpy_ops,np,random.normal,plot_learned_graph,1891,19, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_learned_graph,1892,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_learned_graph,1914,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_learned_graph,1916,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_graph_mismatch,2024,11,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_graph_mismatch,2038,15,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_graph_mismatch,2068,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_graph_mismatch,2068,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_graph_mismatch,2069,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_graph_mismatch,2069,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_graph_mismatch,2070,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,multiplication,plot_graph_mismatch,2070,40,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_graph_mismatch,2086,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_hotspots,2174,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2247,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2281,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2291,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2308,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2320,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2328,13,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2342,14,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,arithmetic_ops,arithmetic,addition,plot_evidence_transitions,2346,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,import,numpy,np,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/plot_utils.py,import,scipy.spatial.transform,Rotation,,18,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/profile_utils.py,arithmetic_ops,arithmetic,subtraction,linebreak_long_strings,35,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/profile_utils.py,arithmetic_ops,arithmetic,addition,linebreak_long_strings,41,39,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/profile_utils.py,arithmetic_ops,arithmetic,addition,bar_chart_cumtime,84,53,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/profile_utils.py,arithmetic_ops,arithmetic,addition,bar_chart_cumtime,87,44,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,load_models_from_dir,89,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,get_reverse_rotation,218,11,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,subtraction,get_reverse_rotation,218,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,264,40,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,267,28,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,check_rotation_accuracy,267,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,268,28,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,check_rotation_accuracy,268,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,269,28,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,check_rotation_accuracy,269,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,282,44,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,285,32,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,check_rotation_accuracy,285,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,286,32,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,check_rotation_accuracy,286,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,modulo,check_rotation_accuracy,287,32,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,check_rotation_accuracy,287,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,multiplication,get_pose_error,397,21,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,multiplication,print_overall_stats,429,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_overall_stats,429,8,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,print_overall_stats,430,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_overall_stats,438,26,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_overall_stats,440,64,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_overall_stats,440,18,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,multiplication,print_unsupervised_stats,451,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_unsupervised_stats,451,8,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,multiplication,print_unsupervised_stats,456,8,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_unsupervised_stats,456,8,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,print_unsupervised_stats,457,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,print_unsupervised_stats,479,18,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_unsupervised_stats,482,64,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,print_unsupervised_stats,482,18,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,calculate_tpr,497,8,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,calculate_tpr,500,15,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,calculate_tpr,500,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,calculate_fpr,513,8,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,division,calculate_fpr,516,15,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,calculate_fpr,516,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,maybe_rename_existing_file,882,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,maybe_rename_existing_file,882,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,arithmetic_ops,arithmetic,addition,maybe_rename_existing_directory,901,19,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,import,numpy,np,,18,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/utils/logging_utils.py,import,scipy.spatial.transform,Rotation,,22,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/monty_base.py,arithmetic_ops,arithmetic,addition,load_state_dict,367,25,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/monty_base.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,multiplication,check_terminal_conditions,148,41,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,subtraction,_combine_votes,354,38,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,addition,_combine_votes,381,45,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,multiplication,_combine_votes,382,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,addition,set_detected_object,792,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,subtraction,_add_displacements,1057,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,subtraction,get_graph_node_ids,1283,34,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,addition,_get_all_node_features,1473,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,arithmetic_ops,arithmetic,multiplication,_get_empty_feature_arrays,1505,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,import,numpy,np,,13,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/graph_matching.py,import,scipy.spatial.transform,Rotation,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,__init__,110,66,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,__init__,112,32,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,optimize,217,27,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,optimize,219,43,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,optimize,222,35,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,optimize,222,35,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,optimize,223,35,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,optimize,223,35,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,optimize,226,25,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,numpy_ops,np,random.randn,add_objects,247,23, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,addition,add_objects,248,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,addition,train_sdrs,311,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,matrix_multiplication,train_sdrs,337,28,@ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,train_sdrs,340,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,addition,train_sdrs,347,45,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,train_sdrs,347,46,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,train_sdrs,348,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,train_sdrs,348,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,modulo,train_sdrs,352,33,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,map_to_overlaps,443,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,map_to_overlaps,444,27,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,addition,map_to_overlaps,446,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,division,map_to_overlaps,446,29,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,map_to_overlaps,446,29,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,map_to_overlaps,446,30,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,division,add_overlaps,468,35,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,addition,add_overlaps,469,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,multiplication,add_overlaps,469,13,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,addition,add_overlaps,471,13,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,collect_evidences,591,37,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,collect_evidences,604,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,matrix_multiplication,_calculate_feature_evidence_sdr_for_all_nodes,701,19,@ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,division,_calculate_feature_evidence_sdr_for_all_nodes,702,30,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_sdr_for_all_nodes,702,31,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_sdr_for_all_nodes,702,56,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_sdr_matching.py,import,numpy,np,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,extract_and_add_features,150,18,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,multiplication,extract_and_add_features,189,53,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,division,extract_and_add_features,192,49,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,extract_and_add_features,192,50,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,multiplication,extract_and_add_features,195,25,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,division,extract_and_add_features,200,25,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,extract_and_add_features,200,26,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,floor_division,observations_to_comunication_protocol,234,25,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,floor_division,observations_to_comunication_protocol,237,23,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,observations_to_comunication_protocol,238,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,multiplication,observations_to_comunication_protocol,238,35,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,division,observations_to_comunication_protocol,243,42,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,add_noise_to_sensor_data,399,35,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,add_noise_to_feat_value,417,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,update_state,505,43,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,update_state,510,43,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,update_state,512,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,multiplication,update_state,513,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,numpy_ops,np,linalg.norm,check_feature_change,682,27, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,check_feature_change,683,20,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,check_feature_change,695,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,check_feature_change,695,49,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,check_feature_change,695,57,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,check_feature_change,699,41,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,check_feature_change,701,59,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,addition,check_feature_change,702,74,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,arithmetic_ops,arithmetic,subtraction,check_feature_change,717,38,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/sensor_modules.py,import,scipy.spatial.transform,Rotation,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,modulo,predefined_call,170,32,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,floor_division,get_depth_at_center,370,12,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,floor_division,get_depth_at_center,370,39,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,convert_motor_state,525,40,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,convert_motor_state,544,53,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,move_close_enough,603,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,move_close_enough,613,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,move_close_enough,623,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,move_close_enough,628,47,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,floor_division,orient_to_object,668,19,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,floor_division,orient_to_object,668,36,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,find_location_to_look_at,727,29,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,find_location_to_look_at,729,39,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,find_location_to_look_at,738,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,find_location_to_look_at,738,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,get_sensors_perc_on_obj,754,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,dynamic_call,789,11,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,touch_object,902,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,touch_object,902,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,touch_object,925,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,touch_object,958,26,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,touch_object,965,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,touch_object,966,12,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,touch_object,966,13,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,dynamic_call,1005,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,dynamic_call,1018,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,_move_tangentially,1074,30,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,_move_tangentially,1075,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,_move_tangentially,1080,30,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,_move_forward,1096,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,tangential_direction,1148,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,tangential_direction,1148,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,tangential_direction,1148,32,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,tangential_direction,1150,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,tangential_direction,1150,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,tangential_direction,1150,37,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,tangential_direction,1150,55,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,tangential_direction,1156,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,tangential_direction,1156,47,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,tangential_direction,1157,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,tangential_direction,1157,47,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,horizontal_distances,1183,29,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,horizontal_distances,1185,12,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,horizontal_distances,1185,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,horizontal_distances,1185,21,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,vertical_distances,1205,29,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,vertical_distances,1207,12,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,vertical_distances,1207,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,vertical_distances,1207,21,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,orienting_angle_from_normal,1259,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,orienting_angle_from_normal,1261,41,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,get_perc_on_obj,1315,33,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,get_perc_on_obj,1317,17,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,get_perc_on_obj,1317,37,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,get_perc_on_obj_semantic,1337,10,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,get_perc_on_obj_semantic,1343,17,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,perform_standard_tang_step,1698,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,perform_standard_tang_step,1698,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,perform_standard_tang_step,1698,32,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,perform_standard_tang_step,1709,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,perform_standard_tang_step,1709,52,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,avoid_revisiting_locations,1891,33,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,avoid_revisiting_locations,1924,64,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,avoid_revisiting_locations,1928,27,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,avoid_revisiting_locations,1928,52,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,modulo,avoid_revisiting_locations,1962,23,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,numpy_ops,np,linalg.norm,conflict_check,1985,15, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,conflict_check,1990,19,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,conflict_check,1997,19,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,numpy_ops,np,linalg.norm,conflict_check,2004,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,attempt_conflict_resolution,2022,49,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,attempt_conflict_resolution,2034,33,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,attempt_conflict_resolution,2034,39,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,attempt_conflict_resolution,2035,22,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,check_for_flipped_pc,2052,50,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,check_for_flipped_pc,2053,19,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,check_for_flipped_pc,2058,53,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,pc_moving_average,2072,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,pc_moving_average,2072,48,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,theta_change,2088,14,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,enforce_pi_bounds,2103,17,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,multiplication,enforce_pi_bounds,2105,17,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,projected_angle_from_vec,2120,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,projected_angle_from_vec,2120,53,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,projected_angle_from_vec,2127,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,projected_vec_from_angle,2146,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,subtraction,projected_vec_from_angle,2148,19,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,projected_vec_from_angle,2148,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,addition,projected_vec_from_angle,2148,46,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,arithmetic_ops,arithmetic,division,projected_vec_from_angle,2148,54,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,scipy_ops,scipy,ndimage.gaussian_filter,find_location_to_look_at,726,35, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,import,numpy,np,,19,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,import,scipy.ndimage,scipy.ndimage,,20,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/motor_policies.py,import,scipy.spatial.transform,rot,,21,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_combine_graph_information,212,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,subtraction,_build_adjacency_graph,261,39,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_build_adjacency_graph,274,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,subtraction,_build_adjacency_graph,304,20,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,division,_initialize_location_mapping,514,21,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,division,_initialize_location_mapping,516,38,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,multiplication,_initialize_location_mapping,518,21,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,floor_division,_initialize_location_mapping,521,20,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,subtraction,_initialize_location_mapping,523,32,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,bitwise_and,_update_grids,560,12,& +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,division,_update_grids,563,28,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,multiplication,_update_grids,566,26,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_update_grids,648,30,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,subtraction,_update_grids,648,30,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_update_grids,659,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,subtraction,_update_grids,659,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_extract_feature_array,726,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,division,_get_new_voxel_location,756,22,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_get_new_voxel_location,756,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,division,_get_new_voxel_features,811,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_get_new_voxel_features,811,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,subtraction,_update_feature_mapping,829,28,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_update_feature_mapping,830,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,addition,_locations_to_grid_ids,862,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,arithmetic_ops,arithmetic,multiplication,_locations_to_grid_ids,862,21,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,sklearn_ops,sklearn,kneighbors_graph,_build_adjacency_graph,293,26, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,scipy_ops,scipy,KDTree,update_model,419,30, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,scipy_ops,scipy,KDTree,set_graph,476,34, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,scipy_ops,scipy,KDTree,_build_graph_from_grids,682,30, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,import,numpy,np,,13,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,import,scipy.spatial,KDTree,,17,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/object_model.py,import,sklearn.neighbors,kneighbors_graph,,18,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,subtraction,update_stats,153,38,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,numpy_ops,np,linalg.norm,get_first_displacement_len,324,19, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,subtraction,get_all_features_on_object,356,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,subtraction,get_num_steps_post_output_goal_generated,432,16,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,multiplication,_add_attr_to_feature_buffer,507,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,multiplication,_add_disp_to_displacement_buffer,546,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,multiplication,_fill_old_values_with_nans,574,19,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,arithmetic_ops,arithmetic,addition,_fill_old_values_with_nans,574,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,import,numpy,np,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/buffer.py,import,scipy.spatial.transform,Rotation,,19,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,receive_votes,187,36,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,multiplication,receive_votes,187,45,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,receive_votes,192,35,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,_update_matches_using_features,404,47,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,addition,_get_new_possible_paths_and_poses,463,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,_match_pose_dependent_features,539,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,division,_match_pose_dependent_features,539,24,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,_match_pose_dependent_features,539,43,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,division,_match_pose_dependent_features,539,51,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,multiplication,_get_informed_possible_poses,620,34,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,multiplication,_get_informed_possible_poses,641,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,multiplication,_match_all_node_features,774,25,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,multiplication,_match_all_node_features,775,23,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,addition,_match_all_node_features,789,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,modulo,_match_all_node_features,801,34,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,_match_all_node_features,802,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,modulo,_match_all_node_features,804,34,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,addition,_match_all_node_features,805,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,subtraction,_match_all_node_features,808,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,addition,_match_all_node_features,811,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,addition,_match_all_node_features,817,38,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,arithmetic_ops,arithmetic,multiplication,_match_all_node_features,824,39,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,sklearn_ops,sklearn,KDTree,receive_votes,168,41, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,sklearn_ops,sklearn,KDTree.query,receive_votes,178,35, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,sklearn_ops,sklearn,KDTree,_get_new_possible_paths_and_poses,456,23, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,sklearn_ops,sklearn,KDTree.query,_get_new_possible_paths_and_poses,467,60, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,import,scipy.spatial.transform,Rotation,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/feature_location_matching.py,import,sklearn.neighbors,KDTree,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,numpy_ops,np,linalg.norm,_check_states_different,239,31, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,subtraction,_check_states_different,239,46,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,bitwise_and,_euc_dist_ignoring_nan,407,15,& +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,numpy_ops,np,linalg.norm,_euc_dist_ignoring_nan,415,19, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,subtraction,_euc_dist_ignoring_nan,415,34,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,subtraction,_update_gsg_logging,434,25,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,subtraction,_compute_graph_mismatch,653,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,addition,_compute_graph_mismatch,658,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,subtraction,_compute_graph_mismatch,662,34,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,addition,_compute_graph_mismatch,666,12,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,addition,_get_target_loc_info,711,66,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,subtraction,_compute_goal_state_for_target_loc,789,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,addition,_compute_goal_state_for_target_loc,802,31,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,multiplication,_compute_goal_state_for_target_loc,811,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,multiplication,_compute_goal_state_for_target_loc,811,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,addition,_compute_goal_state_for_target_loc,813,21,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,multiplication,_compute_goal_state_for_target_loc,822,24,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,modulo,_check_conditions_for_hypothesis_test,999,13,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,arithmetic_ops,arithmetic,multiplication,_check_conditions_for_hypothesis_test,999,34,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/goal_state_generation.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/states.py,import,numpy,np,,10,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_combine_votes,95,38,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,switch_to_exploratory_step,155,41,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,get_output,515,25,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,set_detected_object,574,27,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,modulo,get_unique_pose_if_available,623,26,% +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,get_possible_hypothesis_ids,741,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,get_possible_hypothesis_ids,741,31,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,get_possible_hypothesis_ids,744,43,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,floor_division,_get_initial_hypothesis_space,826,16,// +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_initial_hypothesis_space,830,23,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_add_hypotheses_to_hpspace,851,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_add_hypotheses_to_hpspace,868,29,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_update_evidence,967,20,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_update_evidence,978,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_update_evidence,1033,24,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_update_evidence,1069,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_update_evidence,1079,28,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_update_evidence,1079,28,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_update_evidence,1081,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_update_evidence,1089,22,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,numpy_ops,np,ma.array,_update_evidence_with_vote,1126,30, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,numpy_ops,np,ma.max,_update_evidence_with_vote,1129,42, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_update_evidence_with_vote,1135,11,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,numpy_ops,np,ma.average,_update_evidence_with_vote,1137,38, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,numpy_ops,np,ma.sum,_update_evidence_with_vote,1148,38, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_update_evidence_with_vote,1151,20,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_calculate_evidence_for_new_locations,1252,16,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_calculate_evidence_for_new_locations,1253,18,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_get_pose_evidence_matrix,1305,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_get_pose_evidence_matrix,1305,31,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_get_pose_evidence_matrix,1327,24,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_get_pose_evidence_matrix,1327,24,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_get_pose_evidence_matrix,1327,43,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_get_pose_evidence_matrix,1327,55,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_get_pose_evidence_matrix,1330,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_pose_evidence_matrix,1333,27,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_pose_evidence_matrix,1334,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_get_pose_evidence_matrix,1338,34,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_pose_evidence_matrix,1338,34,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_pose_evidence_matrix,1338,60,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_calculate_feature_evidence_for_all_nodes,1367,25,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_calculate_feature_evidence_for_all_nodes,1368,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_calculate_feature_evidence_for_all_nodes,1369,23,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_calculate_feature_evidence_for_all_nodes,1383,22,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_for_all_nodes,1397,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_for_all_nodes,1403,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_calculate_feature_evidence_for_all_nodes,1403,23,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_for_all_nodes,1404,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_for_all_nodes,1405,23,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,addition,_calculate_feature_evidence_for_all_nodes,1405,35,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_calculate_feature_evidence_for_all_nodes,1411,35,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_calculate_feature_evidence_for_all_nodes,1413,27,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,numpy_ops,np,linalg.norm,_check_for_unique_poses,1442,30, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_check_for_unique_poses,1443,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,matrix_multiplication,_check_for_unique_poses,1460,12,@ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_check_for_unique_poses,1462,40,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_check_for_unique_poses,1462,41,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_check_for_symmetry,1498,15,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_fill_feature_weights_with_default,1577,38,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_all_informed_possible_poses,1628,34,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_threshold_possible_matches,1683,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_threshold_possible_matches,1683,16,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_threshold_possible_matches,1683,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_threshold_possible_matches,1685,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,multiplication,_get_evidence_update_threshold,1772,31,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_get_evidence_update_threshold,1772,31,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,division,_get_node_distance_weights,1783,32,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,arithmetic_ops,arithmetic,subtraction,_get_node_distance_weights,1784,12,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,scipy_ops,scipy,KDTree,_update_evidence_with_vote,1104,29, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,scipy_ops,scipy,KDTree.query,_update_evidence_with_vote,1112,47, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,import,numpy,np,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,import,scipy.spatial,KDTree,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/evidence_matching.py,import,scipy.spatial.transform,Rotation,,17,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,subtraction,get_unique_pose_if_available,103,29,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,addition,get_unique_pose_if_available,103,48,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,subtraction,get_unique_pose_if_available,104,35,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,division,get_object_scale,181,16,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,numpy_ops,np,linalg.norm,get_object_scale,181,16, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,numpy_ops,np,linalg.norm,get_object_scale,181,54, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,division,_compute_possible_matches,216,23,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,subtraction,_predict_using_displacements,305,13,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,addition,_predict_using_displacements,305,44,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,division,_predict_using_displacements,332,20,/ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,arithmetic_ops,arithmetic,subtraction,_add_displacements,407,27,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,import,numpy,np,,12,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/models/displacement_matching.py,import,scipy.spatial.transform,Rotation,,14,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/actions.py,arithmetic_ops,arithmetic,addition,_camel_case_to_snake_case,62,13,+ +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/actions.py,import,numpy,ndarray,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,default_rng,__init__,52,47, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,259,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,sqrt,_random_quaternion_wxyz,259,12, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,subtraction,_random_quaternion_wxyz,259,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,sin,_random_quaternion_wxyz,259,26, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,259,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,259,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,260,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,sqrt,_random_quaternion_wxyz,260,12, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,subtraction,_random_quaternion_wxyz,260,17,- +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,cos,_random_quaternion_wxyz,260,26, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,260,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,260,30,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,261,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,sqrt,_random_quaternion_wxyz,261,12, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,sin,_random_quaternion_wxyz,261,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,261,26,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,261,26,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,262,12,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,sqrt,_random_quaternion_wxyz,262,12, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,numpy_ops,numpy,cos,_random_quaternion_wxyz,262,22, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,262,26,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,arithmetic_ops,arithmetic,multiplication,_random_quaternion_wxyz,262,26,* +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,import,numpy,cos,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,import,numpy,pi,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,import,numpy,sin,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,import,numpy,sqrt,,15,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,import,numpy.random,Generator,,16,0, +/Users/hlee/tbp/tbp.monty/src/tbp/monty/frameworks/actions/action_samplers.py,import,numpy.random,default_rng,,16,0, diff --git a/dmc_configs/dmc_configs/README.md b/dmc_configs/dmc_configs/README.md new file mode 100644 index 0000000..eb1a2b6 --- /dev/null +++ b/dmc_configs/dmc_configs/README.md @@ -0,0 +1,186 @@ +# Experiment Configs for Key Figures + +Below is a summary of configs that correspond to figures in the Demonstrating Monty Capabilities paper, with descriptions motivating the choice of config parameters. + +**Note:** In all experiments, `use_semantic_sensor=False` should be specified. This should be the case once PR #116 is merged, updating the values for PatchViewFinderMountHabitatDatasetArgs etc to be False by default. + +## Figure 1 & 2: Diagramatic Figures With No Experiments + +## Figure 3: Robust Sensorimotor Inference + +Consists of 4 experiments: +- `dist_agent_1lm` (i.e. no noise) +- `dist_agent_1lm_noise` - Sensor noise +- `dist_agent_1lm_randrot` - 5 random rotations (5 rather than e.g. 14 or 32 due to the long time to run the experiments) +- `dist_agent_1lm_randrot_noise` + +Here we are showing the performance of the "standard" version of Monty, using: +- 77 objects +- Goal-state-driven/hypothesis-testing policy active +- A single LM (no voting) + +The main output measure is accuracy and rotation error as a function of noise conditions. + +## Default Parameters for Figures 4+ +Unless specified otherwise, the following figures/experiments use: +- 77 objects +- 5 random rotations +- Sensor noise + +This captures core model performance in a realistic setting. + +## Figure 4: Rapid Inference with Voting + +Consists of 5 experiments: +- `dist_agent_1lm_randrot_noise` +- `dist_agent_2lm_randrot_noise` +- `dist_agent_4lm_randrot_noise` +- `dist_agent_8lm_randrot_noise` +- `dist_agent_16lm_randrot_noise` + +This means performance is evaluated with: +- 77 objects +- Goal-state-driven/hypothesis-testing policy active +- Sensor noise and 5 random rotations +- Voting over 1, 2, 4, 8, or 16 LMs + +The main output measure is accuracy and rotation error as a function of number of LMs. + +**TODO:** +- Config builders for arbitrary numbers of LMs are not currently included in `dmc_eval_experiments.py`. +- Comparable configs should be used to generate views for evaluated rotations to pass to ViT model for comparison. + +## Figure 5: Rapid Inference with Model-Based Policies + +Consists of 3 experiments: +- `dist_agent_1lm_randrot_noise_nohyp` - No hypothesis-testing +- `dist_agent_1lm_randrot_noise_moderatehyp` - Occasional hypothesis-testing + - Should specify: + - elapsed_steps_factor=20 + - min_post_goal_success_steps=10 +- `dist_agent_1lm_randrot_noise` - Default, frequent hypothesis-testing + - Should specify: + - elapsed_steps_factor=10 + - min_post_goal_success_steps=5 + +This means performance is evaluated with: +- 77 objects +- Sensor noise and 5 random rotations +- No voting +- Varying levels of hypothesis-testing + +The main output measure is accuracy and rotation error as a function of hypothesis-testing policy. + +**TODO:** +- These configs need to be specified. + +## Figure 6: Rapid Learning + +Consists of 6 experiments: +- `dist_agent_1lm_randrot_nohyp_1rot_trained` +- `dist_agent_1lm_randrot_nohyp_2rot_trained` +- `dist_agent_1lm_randrot_nohyp_4rot_trained` +- `dist_agent_1lm_randrot_nohyp_8rot_trained` +- `dist_agent_1lm_randrot_nohyp_16rot_trained` +- `dist_agent_1lm_randrot_nohyp_32rot_trained` + +This means performance is evaluated with: +- 77 objects +- 5 random rotations +- NO sensor noise* +- NO hypothesis-testing* +- No voting +- Varying numbers of rotations trained on (evaluations use different baseline models) + +*No hypothesis-testing as the ViT model comparison only receives one view and cannot move around object, and no noise since Sensor-Module noise does not have a clear analogue for the ViT model. + +The main output measure is accuracy and rotation error as a function of training rotations. + +**Notes:** +- Training rotations should be structured: + 1. First 6 rotations = cube faces + 2. Next 8 rotations = cube corners + 3. Remaining = random rotations (as otherwise introduces redundancy) + +**TODO:** +- Configs need to be specified +- Comparable configs needed for ViT model comparison + +## Figure 7: Computationally Efficient Learning and Inference + +Consists of 8 experiments: + +### Inference (7 experiments): +- `dist_agent_1lm_randrot_nohyp_x_percent_5p` - 5% threshold + - `evidence_update_threshold=x_percent_threshold` # Evidence update threshold is the same as x-percent threshold for determining convergence. +- `dist_agent_1lm_randrot_nohyp_x_percent_10p` - 10% threshold +- `dist_agent_1lm_randrot_nohyp_x_percent_15p` - 15% threshold +- `dist_agent_1lm_randrot_nohyp_x_percent_20p` - 20% threshold (default for other experiments) +- `dist_agent_1lm_randrot_nohyp_x_percent_30p` - 30% threshold +- `dist_agent_1lm_randrot_nohyp_x_percent_30p_evidence_update_all` + - 30% x-percent threshold for *convergence* + - Effectively >100% threshold for which hypotheses to test, i.e. all hypotheses are tested, even those with negative evidence; determined by setting `evidence_update_threshold='all' + +**Notes:** +- For the first 5 experiments above, x-percent threshold determines the threshold at which the LM determines it has converged. In addition we set `evidence_update_threshold=x_percent_threshold`, so that this same threshold also determines which evidence values are updated. +- For the final experiment, these are separated out as noted. + +This means performance is evaluated with: +- 77 objects +- 5 random rotations +- No sensor noise* +- No hypothesis-testing* +- No voting + +*Due to ViT model comparison. + +The main output measure is accuracy and FLOPs as a function of x-percent threshold. + +### Training (1 experiment): +- `dist_agent_77obj_1rot_trained`** + +**Single rotation evaluation due to FLOPs counting overhead, so we will extrapolate total FLOPs to 14 rotations based on this/or can compare to a ViT trained on 1 rotation. + +The main output measure is FLOPs as a function of whether the ViT or Monty is training. + +**TODO:** +- Configs need specification (including `dist_agent_77obj_1rot_trained` in `dmc_pretrain_experiments.py`) +- Comparable config needed to generate views corresponding to the 5 random, evaluated rotations, which can then be passed to the ViT model(s) for comparison. + +## Figure 8: Multi-Modal Transfer + +Consists of 4 experiments: +- `dist_agent_1lm_randrot_noise` - "Standard" Monty ("dist_on_dist") +- `dist_on_touch_1lm_randrot_noise` - "dist_on_touch" +- `touch_agent_1lm_randrot_noise` - "touch_on_touch" baseline +- `touch_on_dist_1lm_randrot_noise` - "touch_on_dist" + +This means performance is evaluated with: +- 77 objects +- 5 random rotations +- Sensor noise +- Hypothesis-testing policy active +- No voting + +The main output measure is accuracy and rotation error for within/across modality inference. + +## Figure 9: Structured Object Representations + +Consists of 1 experiment: +- `dist_agent_1lm_randrot_noise_10simobj` + +This means performance is evaluated with: +- 10 morphologically similar objects +- Random rotations +- Sensor noise +- Hypothesis-testing policy active +- No voting + +The main output measure is a dendrogram showing evidence score clustering for the 10 objects. + +**Notes:** +- Although evaluating on 10 objects, the model is trained on 77 objects. +- We need to run this experiment with SELECTIVE logging on so we get the evidence values to analyze. + +**TODO:** +- Config needs specification, including training config for similar objects in `dmc_pretrain_experiments.py`. \ No newline at end of file diff --git a/dmc_configs/dmc_configs/dmc_eval_experiments.py b/dmc_configs/dmc_configs/dmc_eval_experiments.py index 9016eea..a4e4e55 100644 --- a/dmc_configs/dmc_configs/dmc_eval_experiments.py +++ b/dmc_configs/dmc_configs/dmc_eval_experiments.py @@ -13,15 +13,10 @@ This module defines a suite of evaluation experiments using pretrained models generated by `dmc_pretraining_experiments.py`. The core experiments are - `dist_agent_1lm` - - `surf_agent_1lm` - `touch_agent_1lm` - `dist_agent_1lm_nohyp` - - `surf_on_dist` - `touch_on_dist` - - `dist_on_surf` - - `touch_on_surf` - `dist_on_touch` - - `surf_on_touch` - `dist_agent_2lm` - `dist_agent_5lm` - `dist_agent_9lm` @@ -32,7 +27,7 @@ combinations of noise and random object rotations. For example, for `dist_agent_1lm`, we also have `dist_agent_1lm_noise` and `dist_agent_1lm_randrot`, and `dist_agent_1lm_randrot_noise`. Furthermore, each of these has a variant that -evaluates loads the corresponding `_10distinctobj` pretrained model and tests +evaluates the corresponding `_10distinctobj` pretrained model and tests on the DISTINCT_OBJECTS dataset. These `_10distinctobj` variants are generated automatically as a convenience. Other variants-creating functions have default arguments they won't work for every experiment, so noise/randrot variants need to be @@ -46,7 +41,7 @@ On style: Unlike `ycb_experiments.py`, this often prefers functions to return configs over copying and modifying them (for the most part). For example, we have the functions `get_fc_dist_patch_config()` and `get_fc_surf_patch_config()` which return -default feature-chang esensor module configs. +default feature-change sensor module configs. This approach has two main benefits: @@ -54,9 +49,9 @@ back to find which sensor or learning module an experiment uses, we can just look at the function that returns the config. In this way, the functions are an easy way to look up defaults. - - 2. Parameterize configs. This is especially useful when creating multi-LM + 2. Parameterize configs. This is especially useful when creating multi-LM experiments or deleting color information from sensor or learning modules in the - case of touch-only (no color)experiments. + case of touch-only (no color) experiments. The config 'getter'functions defined here are - `get_dist_evidence_lm_config` @@ -68,7 +63,10 @@ - `get_surf_motor_config` At present, all experiments use `EvidenceGraphLM` learning modules, `FeatureChangeSM` -sensor modules, and goal-state-driven motor systems. +sensor modules. + +The goal-state-driven motor system ("hypothesis-testing policy") is used unless a +config explicitly modifies this (e.g. `dist_agent_1lm_nohyp`). We also have functions to generate experiment variants with sensor noise, random rotations, or operate on the DISTINCT_OBJECTS dataset. @@ -82,7 +80,7 @@ will not load the model trained on all 77 objects. The variant-producing functions add suffixes to the logging config `run_name`. -For consistency, prefer the following order of suffixes: `_randrot`, `_noise`, +For consistency, the following order of suffixes is preferred: `_randrot`, `_noise`, `_10distinctobj`. Other conventions/expectations here: - The logging config's `run_name` should be set and match the experiment key. - The logging config's `output_dir` should be set to `OUTPUT_DIR`. @@ -94,7 +92,6 @@ - Experiments are checked to make sure no two configs have the same `output_dir` / `run_name` pair to ensure there is no conflict in output paths. - Logging can be modified or disabled depending on global variables (see below). - """ import copy @@ -616,37 +613,6 @@ def make_10distinctobj_variant(template: dict) -> dict: ), ) -surf_agent_1lm = dict( - experiment_class=MontyObjectRecognitionExperiment, - experiment_args=EvalExperimentArgs( - model_name_or_path=str(PRETRAIN_DIR / "surf_agent_1lm/pretrained"), - n_eval_epochs=len(TEST_ROTATIONS), - max_total_steps=MAX_TOTAL_STEPS, - max_eval_steps=MAX_EVAL_STEPS, - ), - logging_config=ParallelEvidenceLMLoggingConfig(run_name="surf_agent_1lm"), - monty_config=SurfaceAndViewMontyConfig( - monty_class=MontyForEvidenceGraphMatching, - monty_args=MontyArgs(min_eval_steps=MIN_EVAL_STEPS), - sensor_module_configs=dict( - sensor_module_0=get_fc_surf_patch_config(), - sensor_module_1=get_view_finder_config(), - ), - learning_module_configs=dict( - learning_module_0=get_surf_evidence_lm_config(), - ), - motor_system_config=get_surf_motor_config(), - ), - # Set up environment. - dataset_class=ED.EnvironmentDataset, - dataset_args=SurfaceViewFinderMountHabitatDatasetArgs(), - eval_dataloader_class=ED.InformedEnvironmentDataLoader, - eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( - object_names=SHUFFLED_YCB_OBJECTS, - object_init_sampler=PredefinedObjectInitializer(rotations=TEST_ROTATIONS), - ), -) - touch_agent_1lm = dict( experiment_class=MontyObjectRecognitionExperiment, experiment_args=EvalExperimentArgs( @@ -684,10 +650,6 @@ def make_10distinctobj_variant(template: dict) -> dict: dist_agent_1lm_randrot = make_randrot_variant(dist_agent_1lm) dist_agent_1lm_randrot_noise = make_randrot_noise_variant(dist_agent_1lm) -surf_agent_1lm_noise = make_noise_variant(surf_agent_1lm) -surf_agent_1lm_randrot = make_randrot_variant(surf_agent_1lm) -surf_agent_1lm_randrot_noise = make_randrot_noise_variant(surf_agent_1lm) - touch_agent_1lm_noise = make_noise_variant(touch_agent_1lm, color=False) touch_agent_1lm_randrot = make_randrot_variant(touch_agent_1lm) touch_agent_1lm_randrot_noise = make_randrot_noise_variant(touch_agent_1lm, color=False) @@ -715,26 +677,12 @@ def make_10distinctobj_variant(template: dict) -> dict: ------------------------------------------------------------------------------ """ -# Trained on distant agent. -surf_on_dist = copy.deepcopy(surf_agent_1lm) -surf_on_dist["experiment_args"].model_name_or_path = str( - PRETRAIN_DIR / "dist_agent_1lm/pretrained" -) -surf_on_dist["logging_config"].run_name = "surf_on_dist" - touch_on_dist = copy.deepcopy(touch_agent_1lm) touch_on_dist["experiment_args"].model_name_or_path = str( PRETRAIN_DIR / "dist_agent_1lm/pretrained" ) touch_on_dist["logging_config"].run_name = "touch_on_dist" -# Trained on surface agent. -dist_on_surf = copy.deepcopy(dist_agent_1lm) -dist_on_surf["experiment_args"].model_name_or_path = str( - PRETRAIN_DIR / "surf_agent_1lm/pretrained" -) -dist_on_surf["logging_config"].run_name = "dist_on_surf" - touch_on_surf = copy.deepcopy(touch_agent_1lm) touch_on_surf["experiment_args"].model_name_or_path = str( PRETRAIN_DIR / "surf_agent_1lm/pretrained" @@ -754,45 +702,17 @@ def make_10distinctobj_variant(template: dict) -> dict: get_dist_evidence_lm_config(color=False) ) -# Trained on touch agent. Have to remove hsv feature from sensors and learning modules. -surf_on_touch = copy.deepcopy(surf_agent_1lm) -surf_on_touch["experiment_args"].model_name_or_path = str( - PRETRAIN_DIR / "touch_agent_1lm/pretrained" -) -surf_on_touch["logging_config"].run_name = "surf_on_touch" -surf_on_touch["monty_config"].sensor_module_configs["sensor_module_0"] = ( - get_fc_surf_patch_config(color=False) -) -surf_on_touch["monty_config"].learning_module_configs["learning_module_0"] = ( - get_surf_evidence_lm_config(color=False) -) - # Noisy/random rotation variants # ------------------------------------------------------------------------------ -surf_on_dist_noise = make_noise_variant(surf_on_dist) -surf_on_dist_randrot = make_randrot_variant(surf_on_dist) -surf_on_dist_randrot_noise = make_randrot_noise_variant(surf_on_dist) touch_on_dist_noise = make_noise_variant(touch_on_dist, color=False) touch_on_dist_randrot = make_randrot_variant(touch_on_dist) touch_on_dist_randrot_noise = make_randrot_noise_variant(touch_on_dist, color=False) -dist_on_surf_noise = make_noise_variant(dist_on_surf) -dist_on_surf_randrot = make_randrot_variant(dist_on_surf) -dist_on_surf_randrot_noise = make_randrot_noise_variant(dist_on_surf) - -touch_on_surf_noise = make_noise_variant(touch_on_surf, color=False) -touch_on_surf_randrot = make_randrot_variant(touch_on_surf) -touch_on_surf_randrot_noise = make_randrot_noise_variant(touch_on_surf, color=False) - dist_on_touch_noise = make_noise_variant(dist_on_touch, color=False) dist_on_touch_randrot = make_randrot_variant(dist_on_touch) dist_on_touch_randrot_noise = make_randrot_noise_variant(dist_on_touch, color=False) -surf_on_touch_noise = make_noise_variant(surf_on_touch, color=False) -surf_on_touch_randrot = make_randrot_variant(surf_on_touch) -surf_on_touch_randrot_noise = make_randrot_noise_variant(surf_on_touch, color=False) - """ ------------------------------------------------------------------------------ 2 LM models @@ -1012,15 +932,11 @@ def make_10distinctobj_variant(template: dict) -> dict: CONFIGS = { # 1 LM models "dist_agent_1lm": dist_agent_1lm, - "surf_agent_1lm": surf_agent_1lm, "touch_agent_1lm": touch_agent_1lm, # - noise and randrot versions "dist_agent_1lm_noise": dist_agent_1lm_noise, "dist_agent_1lm_randrot": dist_agent_1lm_randrot, "dist_agent_1lm_randrot_noise": dist_agent_1lm_randrot_noise, - "surf_agent_1lm_noise": surf_agent_1lm_noise, - "surf_agent_1lm_randrot": surf_agent_1lm_randrot, - "surf_agent_1lm_randrot_noise": surf_agent_1lm_randrot_noise, "touch_agent_1lm_noise": touch_agent_1lm_noise, "touch_agent_1lm_randrot": touch_agent_1lm_randrot, "touch_agent_1lm_randrot_noise": touch_agent_1lm_randrot_noise, @@ -1030,31 +946,15 @@ def make_10distinctobj_variant(template: dict) -> dict: "dist_agent_1lm_nohyp_randrot": dist_agent_1lm_nohyp_randrot, "dist_agent_1lm_nohyp_randrot_noise": dist_agent_1lm_nohyp_randrot_noise, # Multimodal transfer - "surf_on_dist": surf_on_dist, "touch_on_dist": touch_on_dist, - "dist_on_surf": dist_on_surf, - "touch_on_surf": touch_on_surf, "dist_on_touch": dist_on_touch, - "surf_on_touch": surf_on_touch, # - noise and randrot versions - "surf_on_dist_noise": surf_on_dist_noise, - "surf_on_dist_randrot": surf_on_dist_randrot, - "surf_on_dist_randrot_noise": surf_on_dist_randrot_noise, "touch_on_dist_noise": touch_on_dist_noise, "touch_on_dist_randrot": touch_on_dist_randrot, "touch_on_dist_randrot_noise": touch_on_dist_randrot_noise, - "dist_on_surf_noise": dist_on_surf_noise, - "dist_on_surf_randrot": dist_on_surf_randrot, - "dist_on_surf_randrot_noise": dist_on_surf_randrot_noise, - "touch_on_surf_noise": touch_on_surf_noise, - "touch_on_surf_randrot": touch_on_surf_randrot, - "touch_on_surf_randrot_noise": touch_on_surf_randrot_noise, "dist_on_touch_noise": dist_on_touch_noise, "dist_on_touch_randrot": dist_on_touch_randrot, "dist_on_touch_randrot_noise": dist_on_touch_randrot_noise, - "surf_on_touch_noise": surf_on_touch_noise, - "surf_on_touch_randrot": surf_on_touch_randrot, - "surf_on_touch_randrot_noise": surf_on_touch_randrot_noise, # Multi-LM models "dist_agent_2lm": dist_agent_2lm, "dist_agent_2lm_noise": dist_agent_2lm_noise, diff --git a/floppy/.gitignore b/floppy/.gitignore new file mode 100644 index 0000000..e509c03 --- /dev/null +++ b/floppy/.gitignore @@ -0,0 +1,179 @@ +# User added +results/ + +# Created by https://www.toptal.com/developers/gitignore/api/python +# Edit at https://www.toptal.com/developers/gitignore?templates=python + +### Python ### +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/#use-with-ide +.pdm.toml + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +### Python Patch ### +# Poetry local configuration file - https://python-poetry.org/docs/configuration/#local-configuration +poetry.toml + +# ruff +.ruff_cache/ + +# LSP config files +pyrightconfig.json + +# End of https://www.toptal.com/developers/gitignore/api/python diff --git a/floppy/README.md b/floppy/README.md new file mode 100644 index 0000000..60b7f73 --- /dev/null +++ b/floppy/README.md @@ -0,0 +1,259 @@ +# Floppy: FLOP Analysis and Counting Framework + +Floppy is a framework for analyzing and counting floating-point operations (FLOPs) in Python code, with special focus on numerical computations using NumPy, SciPy, and scikit-learn. + +This repository was developed in part during for the Demonstrating Monty Capabilities project. + +## Overview + +This framework provides multiple approaches to FLOP counting in the `floppy.counting` module. + +1. Operation Interception via TrackedArray wrapper +2. Function wrapping for high-level operations +3. Manual FLOP counting for complex operations + +Multiple approaches are necessary because numerical operations in Python are implemented in different ways: + +1. NumPy's low-level operations are implemented through the ufunc system, which we can intercept using TrackedArray's `__array_ufunc__` interface +2. Higher-level functions like `np.matmul` or `np.linalg.norm` don't use ufuncs, so we need explicit function wrapping to count their FLOPs +3. Complex operations from SciPy and scikit-learn (like KD-tree queries) are implemented by overriding methods in Monty directly, because these are harder to intercept. + +In addition, it contains code for static code analysis in `floppy.analysis` to automatically identify operations that contribute to potential FLOP operations. + +## Static Code Analysis + +The static code analysis is implemented in `floppy.analysis.analyzer.py`. It uses Python's `ast` module to parse source code and identify operations that could contribute to FLOP operations. The analyzer tracks: + +### Function Calls + +- **NumPy Operations**: Tracks all NumPy function calls, including ufuncs, linear algebra operations, and array manipulations +- **SciPy Operations**: Identifies SciPy function calls, particularly from spatial and linear algebra modules +- **scikit-learn Operations**: Captures machine learning operations that may involve significant numerical computations + +### Import Analysis + +Tracks all imports related to numerical computing libraries to understand dependencies and potential FLOP sources: + +- NumPy imports (e.g., `import numpy as np`, `from numpy import array`) +- SciPy imports (e.g., `from scipy.spatial import KDTree`) +- scikit-learn imports (e.g., `from sklearn.neighbors import NearestNeighbors`) + +### Usage Example + +Analyze a file: + +```python +from floppy.flop_analysis.core.analyzer import FlopAnalyzer + +analyzer = FlopAnalyzer() +analyzer.analyze_file('example_code.py') +``` + +Analyze a directory: + +```python +analyzer.analyze_directory('path/to/code') +``` + +The analysis results include: + +- File-level breakdown of numerical operations +- Location information (line numbers) for each operation +- Import dependencies +- Aggregated statistics across multiple files + +This static analysis complements the runtime FLOP counting by helping identify where FLOPs might occur in the codebase, even before execution. + +## Counting Approaches + +### TrackedArray Wrapper + +Intercepts NumPy array operations through the `__array_ufunc__` interface to count FLOPs for: + +- Basic arithmetic operations (+, -, *, /) +- Element-wise operations (np.add, np.multiply, etc.) +- Broadcasting operations +- Reduction operations (sum, mean) + +Example: + +```python +from floppy.flop_counting.counter import FlopCounter + +with FlopCounter() as counter: + a = np.array([[1, 2], [3, 4]]) # Automatically wrapped as TrackedArray + b = a + 1 # Counts one FLOP per element +``` + +### Function Wrapping + +Handles higher-level NumPy/SciPy operations through explicit wrappers: + +- Matrix multiplication (np.matmul, @) +- Linear algebra operations (np.linalg.norm, inv, etc.) +- Statistical operations (mean, std, var) +- Trigonometric functions + +Example: + +```python +from floppy.flop_counting.counter import FlopCounter + +with FlopCounter() as counter: + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + result = np.matmul(a, b) # Counts 2*M*N*P FLOPs +``` + +### Individually Wrapped Complex Operations + +Manual FLOP counting for the following methods in Monty: + +- `tbp.monty.frameworks.models.evidence_matching.EvidenceGraphLM._update_evidence_with_vote` +- `tbp.monty.frameworks.models.evidence_matching.EvidenceGraphLM._calculate_evidence_for_new_locations` +- `tbp.monty.frameworks.models.goal_state_generation.EvidenceGoalStateGenerator._compute_graph_mismatch` + +The FLOP counting for these operations is done by inheriting from the above classes (e.g. `EvidenceGraphLM` as `FlopCounterEvidenceGraphLM`) and overriding the above methods to include FLOP counting. + +Example: + +```python +class FlopCounterEvidenceGraphLM(EvidenceGraphLM): + + def _update_evidence_with_vote(self, *args, **kwargs): + # ... existing code ... + ... = tree.query(...) + + # Custom code to count FLOPs for KDTree query + num_search_points = ... + num_reference_points = ... + ... + kdtree_query_flops = ... + self.flop_counter.add_flops(kdtree_query_flops) + + # ... remainder ofexisting code ... +``` + +#### FLOPs for KDTree Construction and Query + +KDTree operations are one of the key components we track in Monty's evidence matching system. + +**KDTree Construction:** +The construction of a k-d tree has a complexity of $O(kn \log_2(n))$ FLOPs, where: + +- $n$ is the number of points in the dataset +- $k$ is the number of dimensions +- $\log_2(n)$ represents the average depth of the tree + +For each level of the tree ($\log_2(n)$ levels), we need to: + +1. Find the median along the current dimension ($O(n)$ operations) +2. Partition the points ($O(kn)$ operations to compare k-dimensional points) + +**KDTree Query:** +For querying nearest neighbors, our implementation breaks down FLOP counting into several components. Note that we assume a balanced tree structure, which is the default behavior in [SciPy's KDTree implementation (balanced_tree=True)](https://docs.scipy.org/doc/scipy-1.15.0/reference/generated/scipy.spatial.KDTree.html): + +1. **Tree Traversal:** + - FLOPs = num_search_points × dim × log₂(num_reference_points) + - Represents operations needed to traverse the tree to the appropriate leaf nodes + - This logarithmic complexity is guaranteed by the balanced tree structure + +2. **Distance Calculations:** + - FLOPs = num_search_points × num_examined_points × (3 $\times$ dim + dim + 1) + - Where num_examined_points = log₂(num_reference_points) due to balanced tree property + - 3 operations per dimension (subtract, square, add) + - dim additions for summing + - 1 square root operation + +3. **Heap Operations:** + - FLOPs = num_search_points × num_examined_points × log₂(k) + - Where k is the number of nearest neighbors requested (vote_nn) + - Maintains priority queue for k-nearest neighbors + +4. **Bounding Box Checks:** + - FLOPs = num_search_points × num_examined_points × dim + - Represents comparisons against bounding box boundaries + +Total query FLOPs = traversal_flops + distance_flops + heap_flops + bounding_box_flops + +Where: + +- num_search_points: number of query points +- num_reference_points: number of points in the KD-tree +- dim: dimensionality of the points +- num_examined_points: estimated as log₂(num_reference_points) + +Note: These are theoretical approximations. Actual FLOP counts may vary based on: + +- Data distribution +- Tree balance +- Search radius/nearest neighbor parameters +- Optimizations in the underlying SciPy implementation + +## Dependencies + +Floppy requires the same dependencies as Monty because it is running Monty code. There are no additional dependencies for counting. + +## Usage + +### FLOP Counting + +To count FLOPs in Monty: + +```bash +cd ~/tbp/monty_labs/floppy +python run_flop_counter.py -e +``` + +Results are saved in `~/tbp/monty_lab/floppy/results/flop_traces.csv`. + +To count FLOPs in your own code: + +```python +from floppy.counting.counter import FlopCounter + +# Basic usage +with FlopCounter() as counter: + # Your numerical computations here + result = np.matmul(a, b) + print(f"FLOPs: {counter.flops}") + +# With detailed logging +from logging import getLogger +logger = getLogger("flop_counter") +with FlopCounter(logger=logger) as counter: + result = np.linalg.norm(vector) + print(f"FLOPs: {counter.flops}") +``` + +### Static Code Analysis + +To analyze FLOP operations in source code: + +```bash +python run_static_analysis.py --dir path/to/analyze +``` + +Results are saved in `~/tbp/monty_lab/floppy/results/static_analysis/flop_analysis.csv`. + +## Running Tests + +Add the directory to the Python path: + +```bash +export PYTHONPATH=$PYTHONPATH:~/tbp/monty_labs/floppy +``` + +To run the tests, use: + +```bash +python tests/test_add.py +``` + +**Note:** The tests fail when using `pytest`. I think it is because pytest handles imports and module state differently from running the script directly, and cannot interfere with FlopCounter's monkey-patching. + +## Operations Not Yet Supported + +- [1/2] Method calls, e.g. `a.sum()` (partially supported for ufuncs like `arr.add(arr2)`, but not for methods) +- einsum +- linalg.solve diff --git a/floppy/configs/__init__.py b/floppy/configs/__init__.py new file mode 100644 index 0000000..e21b5cc --- /dev/null +++ b/floppy/configs/__init__.py @@ -0,0 +1,17 @@ +# Copyright 2022-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +from .monty_world_experiments import CONFIGS as MONTY_WORLD +from .pretraining_experiments import CONFIGS as PRETRAININGS +from .ycb_experiments import CONFIGS as YCB + +CONFIGS = dict() +CONFIGS.update(PRETRAININGS) +CONFIGS.update(YCB) +CONFIGS.update(MONTY_WORLD) diff --git a/floppy/configs/follow_ups/__init__.py b/floppy/configs/follow_ups/__init__.py new file mode 100644 index 0000000..0b353cd --- /dev/null +++ b/floppy/configs/follow_ups/__init__.py @@ -0,0 +1,22 @@ +# Copyright 2022-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +import os +import pathlib +import pickle + +current_dir = pathlib.Path(__file__).parent +files = [file for file in os.listdir(current_dir) if file.endswith(".pkl")] +names = [file.split(".")[0] for file in files] + +CONFIGS = dict() +for file, name in zip(files, names): + with open(os.path.join(current_dir, file), "rb") as f: + config = pickle.load(f) + CONFIGS[name] = config diff --git a/floppy/configs/monty_world_experiments.py b/floppy/configs/monty_world_experiments.py new file mode 100644 index 0000000..57b6dc1 --- /dev/null +++ b/floppy/configs/monty_world_experiments.py @@ -0,0 +1,203 @@ +# Copyright 2023-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +import copy +import os + +import numpy as np + +from tbp.monty.frameworks.config_utils.config_args import ( + MontyArgs, + MotorSystemConfigInformedNoTransStepS20, + ParallelEvidenceLMLoggingConfig, + PatchAndViewMontyConfig, +) +from tbp.monty.frameworks.config_utils.make_dataset_configs import ( + EnvInitArgsMontyWorldBrightScenes, + EnvInitArgsMontyWorldDarkScenes, + EnvInitArgsMontyWorldHandIntrusionScenes, + EnvInitArgsMontyWorldMultiObjectScenes, + EnvInitArgsMontyWorldStandardScenes, + EnvironmentDataloaderPerObjectArgs, + EvalExperimentArgs, + PatchViewFinderMontyWorldMountHabitatDatasetArgs, + PredefinedObjectInitializer, + RandomRotationObjectInitializer, + WorldImageDataloaderArgs, + WorldImageDatasetArgs, + WorldImageFromStreamDatasetArgs, + get_env_dataloader_per_object_by_idx, + get_object_names_by_idx, +) +from tbp.monty.frameworks.environments import embodied_data as ED +from tbp.monty.frameworks.environments.two_d_data import NUMENTA_OBJECTS +from tbp.monty.frameworks.experiments import MontyObjectRecognitionExperiment +from tbp.monty.frameworks.models.sensor_modules import ( + DetailedLoggingSM, +) + +from .ycb_experiments import ( + default_all_noisy_sensor_module, + default_evidence_1lm_config, + fe_pretrain_dir, + min_eval_steps, +) + +""" +Experiments for a Monty model trained on photogrammetry-scanned objects, and +then evaluated either on these same objects in simulation, or on these objects in the +real world, using depth images from a mobile device. + +To generate pretrained models, run only_surf_agent_training_numenta_lab_obj + +NOTE these experiments do not currently support running with multi-processing, +therefore ensure you omit the -m flag when running these +""" + +model_path_numenta_lab_obj = os.path.join( + fe_pretrain_dir, + "surf_agent_1lm_numenta_lab_obj/pretrained/", +) + +test_rotations_one = [[0, 0, 0]] + +# Base config for evlauating on the scanned objects in Habitat (i.e. simulation) +base_config_monty_world = dict( + experiment_class=MontyObjectRecognitionExperiment, + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_numenta_lab_obj, + n_eval_epochs=len(test_rotations_one), + max_eval_steps=500, + ), + logging_config=ParallelEvidenceLMLoggingConfig(wandb_group="benchmark_experiments"), + monty_config=PatchAndViewMontyConfig( + learning_module_configs=default_evidence_1lm_config, + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + # Take larger steps (move 20 pixels at a time) + motor_system_config=MotorSystemConfigInformedNoTransStepS20(), + ), + dataset_class=ED.EnvironmentDataset, + dataset_args=PatchViewFinderMontyWorldMountHabitatDatasetArgs(), + train_dataloader_class=ED.InformedEnvironmentDataLoader, + train_dataloader_args=get_env_dataloader_per_object_by_idx(start=0, stop=12), + eval_dataloader_class=ED.InformedEnvironmentDataLoader, + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 12, object_list=NUMENTA_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=test_rotations_one), + ), +) + +# More challenging evaluation on photogrammetry objects; serves as a baseline +# for viewing these objects from a fixed, single view, but in simulation rather than +# with real-world data +# Note we therefore use the basic distant-agent policy without hypothesis-driven +# actions, to be more comparable to the constraints of inference on real-world data +randrot_noise_sim_on_scan_monty_world = copy.deepcopy(base_config_monty_world) +randrot_noise_sim_on_scan_monty_world.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_numenta_lab_obj, + n_eval_epochs=10, + max_eval_steps=500, + ), + monty_config=PatchAndViewMontyConfig( + sensor_module_configs=dict( + sensor_module_0=default_all_noisy_sensor_module, + sensor_module_1=dict( + sensor_module_class=DetailedLoggingSM, + sensor_module_args=dict( + sensor_module_id="view_finder", + save_raw_obs=False, + ), + ), + ), + learning_module_configs=default_evidence_1lm_config, + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + motor_system_config=MotorSystemConfigInformedNoTransStepS20(), + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 12, object_list=NUMENTA_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +# Evaluation on real-world depth data, but trained on photogrammetry scanned objects +world_image_on_scanned_model = copy.deepcopy(base_config_monty_world) +world_image_on_scanned_model.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_numenta_lab_obj, + n_eval_epochs=1, + max_eval_steps=500, + show_sensor_output=False, + ), + dataset_args=WorldImageDatasetArgs( + env_init_args=EnvInitArgsMontyWorldStandardScenes() + ), + train_dataloader_class=ED.SaccadeOnImageDataLoader, + train_dataloader_args=WorldImageDataloaderArgs(), + eval_dataloader_class=ED.SaccadeOnImageDataLoader, + # TODO: write something akin to PredefinedObjectInitializer to automatically + # determine these values + eval_dataloader_args=WorldImageDataloaderArgs( + scenes=list(np.repeat(range(12), 4)), + versions=list(np.tile(range(4), 12)), + # For debugging: + # scenes=[0, 0, 0, 0], + # versions=[0, 1, 2, 3], + ), +) + +# For live-demos, run inference where we constantly look for incoming data streamed +# from the mobile device +world_image_from_stream_on_scanned_model = copy.deepcopy(world_image_on_scanned_model) +world_image_from_stream_on_scanned_model.update( + dataset_args=WorldImageFromStreamDatasetArgs(), + eval_dataloader_class=ED.SaccadeOnImageFromStreamDataLoader, + eval_dataloader_args=dict(), +) + + +bright_world_image_on_scanned_model = copy.deepcopy(world_image_on_scanned_model) +bright_world_image_on_scanned_model.update( + dataset_args=WorldImageDatasetArgs( + env_init_args=EnvInitArgsMontyWorldBrightScenes() + ), +) + +dark_world_image_on_scanned_model = copy.deepcopy(world_image_on_scanned_model) +dark_world_image_on_scanned_model.update( + dataset_args=WorldImageDatasetArgs(env_init_args=EnvInitArgsMontyWorldDarkScenes()), +) + +hand_intrusion_world_image_on_scanned_model = copy.deepcopy( + world_image_on_scanned_model +) +hand_intrusion_world_image_on_scanned_model.update( + dataset_args=WorldImageDatasetArgs( + env_init_args=EnvInitArgsMontyWorldHandIntrusionScenes() + ), +) + +multi_object_world_image_on_scanned_model = copy.deepcopy(world_image_on_scanned_model) +multi_object_world_image_on_scanned_model.update( + dataset_args=WorldImageDatasetArgs( + env_init_args=EnvInitArgsMontyWorldMultiObjectScenes() + ), +) + +CONFIGS = dict( + base_config_monty_world=base_config_monty_world, + world_image_from_stream_on_scanned_model=world_image_from_stream_on_scanned_model, + # ------------- Experiments for Benchmarks Table ------------- + randrot_noise_sim_on_scan_monty_world=randrot_noise_sim_on_scan_monty_world, + world_image_on_scanned_model=world_image_on_scanned_model, + dark_world_image_on_scanned_model=dark_world_image_on_scanned_model, + bright_world_image_on_scanned_model=bright_world_image_on_scanned_model, + hand_intrusion_world_image_on_scanned_model=hand_intrusion_world_image_on_scanned_model, + multi_object_world_image_on_scanned_model=multi_object_world_image_on_scanned_model, +) diff --git a/floppy/configs/pretraining_experiments.py b/floppy/configs/pretraining_experiments.py new file mode 100644 index 0000000..a6e47de --- /dev/null +++ b/floppy/configs/pretraining_experiments.py @@ -0,0 +1,279 @@ +# Copyright 2022-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +import copy +import os + +import numpy as np + +from tbp.monty.frameworks.config_utils.config_args import ( + FiveLMMontyConfig, + MontyArgs, + MontyFeatureGraphArgs, + MotorSystemConfigCurvatureInformedSurface, + MotorSystemConfigNaiveScanSpiral, + PatchAndViewMontyConfig, + PretrainLoggingConfig, + SurfaceAndViewMontyConfig, + get_cube_face_and_corner_views_rotations, +) +from tbp.monty.frameworks.config_utils.make_dataset_configs import ( + EnvironmentDataloaderPerObjectArgs, + ExperimentArgs, + FiveLMMountHabitatDatasetArgs, + PatchViewFinderMountHabitatDatasetArgs, + PredefinedObjectInitializer, + SurfaceViewFinderMontyWorldMountHabitatDatasetArgs, + SurfaceViewFinderMountHabitatDatasetArgs, + get_env_dataloader_per_object_by_idx, + get_object_names_by_idx, +) +from tbp.monty.frameworks.config_utils.policy_setup_utils import ( + make_naive_scan_policy_config, +) +from tbp.monty.frameworks.environments import embodied_data as ED +from tbp.monty.frameworks.environments.two_d_data import NUMENTA_OBJECTS +from tbp.monty.frameworks.environments.ycb import ( + DISTINCT_OBJECTS, + SHUFFLED_YCB_OBJECTS, + SIMILAR_OBJECTS, +) +from tbp.monty.frameworks.experiments import ( + MontySupervisedObjectPretrainingExperiment, +) +from tbp.monty.frameworks.models.displacement_matching import DisplacementGraphLM +from tbp.monty.frameworks.models.sensor_modules import ( + DetailedLoggingSM, + HabitatSurfacePatchSM, +) + +# FOR SUPERVISED PRETRAINING: 14 unique rotations that give good views of the object. +train_rotations_all = get_cube_face_and_corner_views_rotations() + +monty_models_dir = os.getenv("MONTY_MODELS") + +fe_pretrain_dir = os.path.expanduser( + os.path.join(monty_models_dir, "pretrained_ycb_v9") +) + +pre_surf_agent_visual_training_model_path = os.path.join( + fe_pretrain_dir, "supervised_pre_training_all_objects/pretrained/" +) + +supervised_pre_training_base = dict( + experiment_class=MontySupervisedObjectPretrainingExperiment, + experiment_args=ExperimentArgs( + do_eval=False, + n_train_epochs=len(train_rotations_all), + ), + logging_config=PretrainLoggingConfig( + output_dir=fe_pretrain_dir, + ), + monty_config=PatchAndViewMontyConfig( + monty_args=MontyArgs(num_exploratory_steps=500), + learning_module_configs=dict( + learning_module_0=dict( + learning_module_class=DisplacementGraphLM, + learning_module_args=dict( + k=10, + match_attribute="displacement", + tolerance=np.ones(3) * 0.0001, + graph_delta_thresholds=dict( + patch=dict( + distance=0.001, + # Only first pose vector (point normal) is currently used + pose_vectors=[np.pi / 8, np.pi * 2, np.pi * 2], + principal_curvatures_log=[1, 1], + hsv=[0.1, 1, 1], + ) + ), + ), + # NOTE: Learning works with any LM type. For instance you can use + # the following code to run learning with the EvidenceGraphLM: + # learning_module_class=EvidenceGraphLM, + # learning_module_args=dict( + # max_match_distance=0.01, + # tolerances={"patch": dict()}, + # feature_weights=dict(), + # graph_delta_thresholds=dict(patch=dict( + # distance=0.001, + # pose_vectors=[np.pi / 8, np.pi * 2, np.pi * 2], + # principal_curvatures_log=[1, 1], + # hsv=[0.1, 1, 1], + # )), + # ), + # NOTE: When learning with the EvidenceGraphLM or FeatureGraphLM, no + # edges will be added to the learned graphs (also not needed for + # matching) while learning with DisplacementGraphLM is a superset of + # these, i.e. captures all necessary information to do inference with + # any three of the LM types. + ) + ), + motor_system_config=MotorSystemConfigNaiveScanSpiral( + motor_system_args=make_naive_scan_policy_config(step_size=5) + ), # use spiral policy for more even object coverage during learning + ), + dataset_class=ED.EnvironmentDataset, + dataset_args=PatchViewFinderMountHabitatDatasetArgs(), + train_dataloader_class=ED.InformedEnvironmentDataLoader, + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=train_rotations_all), + ), + eval_dataloader_class=ED.InformedEnvironmentDataLoader, # just placeholder + eval_dataloader_args=get_env_dataloader_per_object_by_idx(start=0, stop=1), +) + + +only_surf_agent_training_10obj = copy.deepcopy(supervised_pre_training_base) +only_surf_agent_training_10obj.update( + experiment_args=ExperimentArgs( + n_train_epochs=len(train_rotations_all), + do_eval=False, + ), + monty_config=SurfaceAndViewMontyConfig( + monty_args=MontyFeatureGraphArgs(num_exploratory_steps=1000), + learning_module_configs=dict( + learning_module_0=dict( + learning_module_class=DisplacementGraphLM, + learning_module_args=dict( + k=10, + match_attribute="displacement", + tolerance=np.ones(3) * 0.0001, + graph_delta_thresholds=dict( + patch=dict( + distance=0.01, + pose_vectors=[np.pi / 8, np.pi * 2, np.pi * 2], + principal_curvatures_log=[1.0, 1.0], + hsv=[0.1, 1, 1], + ) + ), + ), + ), + ), + sensor_module_configs=dict( + sensor_module_0=dict( + sensor_module_class=HabitatSurfacePatchSM, + sensor_module_args=dict( + sensor_module_id="patch", + features=[ + "pose_vectors", + "pose_fully_defined", + "on_object", + "object_coverage", + "rgba", + "hsv", + "min_depth", + "mean_depth", + "principal_curvatures", + "principal_curvatures_log", + "gaussian_curvature", + "mean_curvature", + "gaussian_curvature_sc", + "mean_curvature_sc", + ], + save_raw_obs=True, + ), + ), + sensor_module_1=dict( + # No need to extract features from the view finder since it is not + # connected to a learning module (just used at beginning of episode) + sensor_module_class=DetailedLoggingSM, + sensor_module_args=dict( + sensor_module_id="view_finder", + save_raw_obs=True, + ), + ), + ), + motor_system_config=MotorSystemConfigCurvatureInformedSurface(), + ), + dataset_class=ED.EnvironmentDataset, + dataset_args=SurfaceViewFinderMountHabitatDatasetArgs(), + logging_config=PretrainLoggingConfig( + output_dir=fe_pretrain_dir, + run_name="surf_agent_1lm_10distinctobj", + ), + train_dataloader_class=ED.InformedEnvironmentDataLoader, + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=train_rotations_all), + ), +) + +only_surf_agent_training_10simobj = copy.deepcopy(only_surf_agent_training_10obj) +only_surf_agent_training_10simobj.update( + logging_config=PretrainLoggingConfig( + output_dir=fe_pretrain_dir, + run_name="surf_agent_1lm_10similarobj", + ), + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=SIMILAR_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=train_rotations_all), + ), +) + +only_surf_agent_training_allobj = copy.deepcopy(only_surf_agent_training_10obj) +only_surf_agent_training_allobj.update( + logging_config=PretrainLoggingConfig( + output_dir=fe_pretrain_dir, + run_name=f"surf_agent_1lm_{len(SHUFFLED_YCB_OBJECTS)}obj", + ), + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, len(SHUFFLED_YCB_OBJECTS), object_list=SHUFFLED_YCB_OBJECTS + ), + object_init_sampler=PredefinedObjectInitializer(rotations=train_rotations_all), + ), +) + +only_surf_agent_training_numenta_lab_obj = copy.deepcopy(only_surf_agent_training_10obj) +only_surf_agent_training_numenta_lab_obj.update( + logging_config=PretrainLoggingConfig( + output_dir=fe_pretrain_dir, + run_name="surf_agent_1lm_numenta_lab_obj", + ), + dataset_args=SurfaceViewFinderMontyWorldMountHabitatDatasetArgs(), + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 12, object_list=NUMENTA_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=train_rotations_all), + ), +) + +# TODO: these don't use the graph_delta_thresholds of the one LM experiments. Do we +# want to update that? +supervised_pre_training_5lms = copy.deepcopy(supervised_pre_training_base) +supervised_pre_training_5lms.update( + monty_config=FiveLMMontyConfig( + monty_args=MontyArgs(num_exploratory_steps=500), + motor_system_config=MotorSystemConfigNaiveScanSpiral( + motor_system_args=make_naive_scan_policy_config(step_size=5) + ), + ), + dataset_args=FiveLMMountHabitatDatasetArgs(), +) + +supervised_pre_training_5lms_all_objects = copy.deepcopy(supervised_pre_training_5lms) +supervised_pre_training_5lms_all_objects.update( + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, len(SHUFFLED_YCB_OBJECTS), object_list=SHUFFLED_YCB_OBJECTS + ), + object_init_sampler=PredefinedObjectInitializer(rotations=train_rotations_all), + ), +) + +CONFIGS = dict( + supervised_pre_training_base=supervised_pre_training_base, + supervised_pre_training_5lms=supervised_pre_training_5lms, + supervised_pre_training_5lms_all_objects=supervised_pre_training_5lms_all_objects, + only_surf_agent_training_10obj=only_surf_agent_training_10obj, + only_surf_agent_training_10simobj=only_surf_agent_training_10simobj, + only_surf_agent_training_allobj=only_surf_agent_training_allobj, + only_surf_agent_training_numenta_lab_obj=only_surf_agent_training_numenta_lab_obj, +) diff --git a/floppy/configs/ycb_experiments.py b/floppy/configs/ycb_experiments.py new file mode 100644 index 0000000..f37f729 --- /dev/null +++ b/floppy/configs/ycb_experiments.py @@ -0,0 +1,742 @@ +# Copyright 2022-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +import copy +import os + +import numpy as np + +from tbp.monty.frameworks.config_utils.config_args import ( + CSVLoggingConfig, + FiveLMMontySOTAConfig, + MontyArgs, + MotorSystemConfigCurInformedSurfaceGoalStateDriven, + ParallelEvidenceLMLoggingConfig, + PatchAndViewFartherAwaySOTAMontyConfig, + PatchAndViewSOTAMontyConfig, + SurfaceAndViewMontyConfig, + SurfaceAndViewSOTAMontyConfig, + get_cube_face_and_corner_views_rotations, +) +from tbp.monty.frameworks.config_utils.make_dataset_configs import ( + EnvironmentDataloaderMultiObjectArgs, + EnvironmentDataloaderPerObjectArgs, + EvalExperimentArgs, + ExperimentArgs, + FiveLMMountHabitatDatasetArgs, + NoisySurfaceViewFinderMountHabitatDatasetArgs, + PatchViewFinderMountHabitatDatasetArgs, + PredefinedObjectInitializer, + RandomRotationObjectInitializer, + SurfaceViewFinderMountHabitatDatasetArgs, + get_env_dataloader_per_object_by_idx, + get_object_names_by_idx, +) +from tbp.monty.frameworks.environments import embodied_data as ED +from tbp.monty.frameworks.environments.ycb import ( + DISTINCT_OBJECTS, + SIMILAR_OBJECTS, +) +from tbp.monty.frameworks.experiments import MontyObjectRecognitionExperiment +from tbp.monty.frameworks.models.evidence_matching import ( + EvidenceGraphLM, + MontyForEvidenceGraphMatching, +) +from tbp.monty.frameworks.models.goal_state_generation import ( + EvidenceGoalStateGenerator, +) +from tbp.monty.frameworks.models.sensor_modules import ( + DetailedLoggingSM, + FeatureChangeSM, +) + +""" +(all use surface-agent models with 0.01 min dist and 64x64 resolution, +feature change SM, 50 min_steps, 500 max_steps) + +To generate models run: +- supervised_pre_training_base +- only_surf_agent_training_10obj +- only_surf_agent_training_10simobj +- only_surf_agent_training_allobj +- supervised_pre_training_5lms +- supervised_pre_training_5lms_all_objects + +QUICK EVALUATION TESTS: +- 10 objects, 32 known orientations, 1LM, distant agent +- 10 objects, 32 known orientations, 1LM, surface agent +- noise & 10 random rotations, distant agent +- noise & 10 random rotations, distant agent on model learned with distant sensor +- noise & 10 random rotations, surface agent +- no noise & 10 random rotations, surface agent +- noise & 10 random rotations, distant agent, 5LMs +- raw noise & 10 random rotations, surface agent +- 10 similar objects, 32 known orientations, surface agent +- 10 similar objects, noise & 10 random rotations, surface agent +- learning unsupervised + +LONGER EVALUATION RUNS: +(all have 77 objects, best policy & paramters optimized for performance) +- default, 32 rotations, distant agent +- noise & 3 random rotations with 1LM, distant agent +- noise & 3 random rotations with 1LM, surface agent +- noise & 3 random rotations with 5LMs + +For more details, see docs/how-to-use-monty/running-benchmarks.md +and docs/overview/benchmark-experiments.md +""" + +# 14 unique rotations that give good views of the object. Same rotations used +# for supervised pretraining. +test_rotations_all = get_cube_face_and_corner_views_rotations() + +# Limited number of rotations to use for quicker evaluation when doing longer +# runs with all 77 YCB objects. +test_rotations_3 = test_rotations_all[:3] + +monty_models_dir = os.getenv("MONTY_MODELS") + +# v6 : Using TLS for point-normal estimation +# v7 : Updated for State class support + using new feature names like pose_vectors +# v8 : Using separate graph per input channel +# v9 : Using models trained on 14 unique rotations +fe_pretrain_dir = os.path.expanduser( + os.path.join(monty_models_dir, "pretrained_ycb_v9") +) + +model_path_10distinctobj = os.path.join( + fe_pretrain_dir, + "surf_agent_1lm_10distinctobj/pretrained/", +) + +dist_agent_model_path_10distinctobj = os.path.join( + fe_pretrain_dir, + "supervised_pre_training_base/pretrained/", +) + +model_path_10simobj = os.path.join( + fe_pretrain_dir, + "surf_agent_1lm_10similarobj/pretrained/", +) + +model_path_5lms_10distinctobj = os.path.join( + fe_pretrain_dir, + "supervised_pre_training_5lms/pretrained/", +) + +model_path_1lm_77obj = os.path.join( + fe_pretrain_dir, + "surf_agent_1lm_77obj/pretrained/", +) + +model_path_5lms_77obj = os.path.join( + fe_pretrain_dir, + "supervised_pre_training_5lms_all_objects/pretrained/", +) + +# NOTE: maybe lower once we have better policies +# Is not really nescessary for good performance but makes sure we don't just overfit +# on the first few points. +min_eval_steps = 20 + +default_tolerance_values = { + "hsv": np.array([0.1, 0.2, 0.2]), + "principal_curvatures_log": np.ones(2), +} + +default_tolerances = { + "patch": default_tolerance_values +} # features where weight is not specified default weight to 1 +# Everything is weighted 1, except for saturation and value which are not used. +default_feature_weights = { + "patch": { + # Weighting saturation and value less since these might change under different + # lighting conditions. In the future we can extract better features in the SM + # such as relative value changes. + "hsv": np.array([1, 0.5, 0.5]), + } +} + +default_evidence_lm_config = dict( + learning_module_class=EvidenceGraphLM, + learning_module_args=dict( + # mmd of 0.015 get higher performance but slower run time + max_match_distance=0.01, # =1cm + tolerances=default_tolerances, + feature_weights=default_feature_weights, + # smaller threshold reduces runtime but also performance + x_percent_threshold=20, + # Using a smaller max_nneighbors (5 instead of 10) makes runtime faster, + # but reduces performance a bit + max_nneighbors=10, + # Use this to update all hypotheses at every step as previously + # evidence_update_threshold="all", + # Use this to update all hypotheses > x_percent_threshold (faster) + evidence_update_threshold="x_percent_threshold", + # use_multithreading=False, + # NOTE: Currently not used when loading pretrained graphs. + max_graph_size=0.3, # 30cm + num_model_voxels_per_dim=100, + gsg_class=EvidenceGoalStateGenerator, + gsg_args=dict( + goal_tolerances=dict( + location=0.015, # distance in meters + ), # Tolerance(s) when determining goal-state success + elapsed_steps_factor=10, # Factor that considers the number of elapsed + # steps as a possible condition for initiating a hypothesis-testing goal + # state; should be set to an integer reflecting a number of steps + min_post_goal_success_steps=5, # Number of necessary steps for a hypothesis + # goal-state to be considered + x_percent_scale_factor=0.75, # Scale x-percent threshold to decide + # when we should focus on pose rather than determining object ID; should + # be bounded between 0:1.0; "mod" for modifier + desired_object_distance=0.03, # Distance from the object to the + # agent that is considered "close enough" to the object + ), + ), +) + +# Default configs for surface policy which has a different desired object distance +default_surf_evidence_lm_config = copy.deepcopy(default_evidence_lm_config) +default_surf_evidence_lm_config["learning_module_args"]["gsg_args"][ + "desired_object_distance" +] = 0.025 + +# Using a smaller max_nneighbors for the noiseless experiments cuts the runtime +# in almost half without negatively affecting performance. For the noisy experiments a +# higher max_nneighbors is necessary so we use the default config above for +# those. +lower_max_nneighbors_lm_config = copy.deepcopy(default_evidence_lm_config) +lower_max_nneighbors_lm_config["learning_module_args"]["max_nneighbors"] = 5 +lower_max_nneighbors_surf_lm_config = copy.deepcopy(default_surf_evidence_lm_config) +lower_max_nneighbors_surf_lm_config["learning_module_args"]["max_nneighbors"] = 5 + +default_evidence_1lm_config = dict(learning_module_0=default_evidence_lm_config) +lower_max_nneighbors_1lm_config = dict(learning_module_0=lower_max_nneighbors_lm_config) + +default_evidence_surf_1lm_config = dict( + learning_module_0=default_surf_evidence_lm_config +) +lower_max_nneighbors_surf_1lm_config = dict( + learning_module_0=lower_max_nneighbors_surf_lm_config +) + +lm0_config = copy.deepcopy(default_evidence_lm_config) +lm0_config["learning_module_args"]["tolerances"] = {"patch_0": default_tolerance_values} +lm1_config = copy.deepcopy(default_evidence_lm_config) +lm1_config["learning_module_args"]["tolerances"] = {"patch_1": default_tolerance_values} +lm2_config = copy.deepcopy(default_evidence_lm_config) +lm2_config["learning_module_args"]["tolerances"] = {"patch_2": default_tolerance_values} +lm3_config = copy.deepcopy(default_evidence_lm_config) +lm3_config["learning_module_args"]["tolerances"] = {"patch_3": default_tolerance_values} +lm4_config = copy.deepcopy(default_evidence_lm_config) +lm4_config["learning_module_args"]["tolerances"] = {"patch_4": default_tolerance_values} + +default_5lm_lmconfig = dict( + learning_module_0=lm0_config, + learning_module_1=lm1_config, + learning_module_2=lm2_config, + learning_module_3=lm3_config, + learning_module_4=lm4_config, +) + +default_sensor_features = [ + "pose_vectors", + "pose_fully_defined", + "on_object", + "hsv", + "principal_curvatures_log", +] + +default_sensor_features_surf_agent = [ + "pose_vectors", + "pose_fully_defined", + "on_object", + "object_coverage", + "min_depth", + "mean_depth", + "hsv", + "principal_curvatures", + "principal_curvatures_log", +] + +default_all_noise_params = { + "features": { + "pose_vectors": 2, # rotate by random degrees along xyz + "hsv": 0.1, # add gaussian noise with 0.1 std + "principal_curvatures_log": 0.1, + "pose_fully_defined": 0.01, # flip bool in 1% of cases + }, + "location": 0.002, # add gaussian noise with 0.002 std +} + +default_all_noisy_sensor_module = dict( + sensor_module_class=FeatureChangeSM, + sensor_module_args=dict( + sensor_module_id="patch", + features=default_sensor_features, + save_raw_obs=False, + delta_thresholds={ + "on_object": 0, + "distance": 0.01, + }, + noise_params=default_all_noise_params, + ), +) + +default_all_noisy_surf_agent_sensor_module = dict( + sensor_module_class=FeatureChangeSM, + sensor_module_args=dict( + sensor_module_id="patch", + features=default_sensor_features_surf_agent, + save_raw_obs=False, + delta_thresholds={ + "on_object": 0, + "distance": 0.01, + }, + surf_agent_sm=True, + noise_params=default_all_noise_params, + ), +) + +sm0_config = copy.deepcopy(default_all_noisy_sensor_module) +sm0_config["sensor_module_args"]["sensor_module_id"] = "patch_0" + +sm1_config = copy.deepcopy(default_all_noisy_sensor_module) +sm1_config["sensor_module_args"]["sensor_module_id"] = "patch_1" + +sm2_config = copy.deepcopy(default_all_noisy_sensor_module) +sm2_config["sensor_module_args"]["sensor_module_id"] = "patch_2" + +sm3_config = copy.deepcopy(default_all_noisy_sensor_module) +sm3_config["sensor_module_args"]["sensor_module_id"] = "patch_3" + +sm4_config = copy.deepcopy(default_all_noisy_sensor_module) +sm4_config["sensor_module_args"]["sensor_module_id"] = "patch_4" + +default_5sm_config = dict( + sensor_module_0=sm0_config, + sensor_module_1=sm1_config, + sensor_module_2=sm2_config, + sensor_module_3=sm3_config, + sensor_module_4=sm4_config, + sensor_module_5=dict( + sensor_module_class=DetailedLoggingSM, + sensor_module_args=dict( + sensor_module_id="view_finder", + save_raw_obs=True, + ), + ), +) + +base_config_10distinctobj_dist_agent = dict( + experiment_class=MontyObjectRecognitionExperiment, + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10distinctobj, + n_eval_epochs=len(test_rotations_all), + ), + logging_config=ParallelEvidenceLMLoggingConfig( + wandb_group="benchmark_experiments", + # Comment in for quick debugging (turns of wandb and increases logging) + # wandb_handlers=[], + # python_log_level="DEBUG", + ), + monty_config=PatchAndViewSOTAMontyConfig( + learning_module_configs=lower_max_nneighbors_1lm_config, + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + ), + dataset_class=ED.EnvironmentDataset, + dataset_args=PatchViewFinderMountHabitatDatasetArgs(), + train_dataloader_class=ED.InformedEnvironmentDataLoader, + train_dataloader_args=get_env_dataloader_per_object_by_idx(start=0, stop=10), + eval_dataloader_class=ED.InformedEnvironmentDataLoader, + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=test_rotations_all), + ), +) + +base_config_10distinctobj_surf_agent = copy.deepcopy( + base_config_10distinctobj_dist_agent +) +base_config_10distinctobj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10distinctobj, + n_eval_epochs=len(test_rotations_all), + max_total_steps=5000, # x4 max_eval_steps for surface-policy, x2.5 for + # feature-change SM + ), + monty_config=SurfaceAndViewSOTAMontyConfig( + learning_module_configs=lower_max_nneighbors_surf_1lm_config, + motor_system_config=MotorSystemConfigCurInformedSurfaceGoalStateDriven(), + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + ), + dataset_args=SurfaceViewFinderMountHabitatDatasetArgs(), +) + +randrot_noise_10distinctobj_dist_agent = copy.deepcopy( + base_config_10distinctobj_dist_agent +) +randrot_noise_10distinctobj_dist_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10distinctobj, + n_eval_epochs=10, # number of random rotations to test for each object + ), + monty_config=PatchAndViewSOTAMontyConfig( + sensor_module_configs=dict( + sensor_module_0=default_all_noisy_sensor_module, + sensor_module_1=dict( + sensor_module_class=DetailedLoggingSM, + sensor_module_args=dict( + sensor_module_id="view_finder", + save_raw_obs=True, + ), + ), + ), + learning_module_configs=default_evidence_1lm_config, + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +# NOTE: This experiment can reach a higher accuracy when using a 10% TH. +randrot_noise_10distinctobj_dist_on_distm = copy.deepcopy( + randrot_noise_10distinctobj_dist_agent +) +randrot_noise_10distinctobj_dist_on_distm.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=dist_agent_model_path_10distinctobj, + n_eval_epochs=10, + ), +) + +randrot_noise_10distinctobj_surf_agent = copy.deepcopy( + randrot_noise_10distinctobj_dist_agent +) +randrot_noise_10distinctobj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10distinctobj, + n_eval_epochs=10, + max_total_steps=5000, # x4 max_eval_steps for surface-policy, x2.5 for + # feature-change SM + ), + monty_config=SurfaceAndViewSOTAMontyConfig( + sensor_module_configs=dict( + sensor_module_0=default_all_noisy_surf_agent_sensor_module, + sensor_module_1=dict( + sensor_module_class=DetailedLoggingSM, + sensor_module_args=dict( + sensor_module_id="view_finder", + save_raw_obs=True, + ), + ), + ), + learning_module_configs=default_evidence_surf_1lm_config, + motor_system_config=MotorSystemConfigCurInformedSurfaceGoalStateDriven(), + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + ), + dataset_args=SurfaceViewFinderMountHabitatDatasetArgs(), +) + +randrot_10distinctobj_surf_agent = copy.deepcopy(base_config_10distinctobj_surf_agent) +randrot_10distinctobj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10distinctobj, + n_eval_epochs=10, + max_total_steps=5000, + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +randrot_noise_10distinctobj_5lms_dist_agent = copy.deepcopy( + randrot_noise_10distinctobj_dist_agent +) +randrot_noise_10distinctobj_5lms_dist_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_5lms_10distinctobj, + n_eval_epochs=10, + min_lms_match=3, + ), + monty_config=FiveLMMontySOTAConfig( + monty_class=MontyForEvidenceGraphMatching, # has custom evidence voting method + learning_module_configs=default_5lm_lmconfig, + sensor_module_configs=default_5sm_config, + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + ), + dataset_args=FiveLMMountHabitatDatasetArgs(), +) + +base_10simobj_surf_agent = copy.deepcopy(base_config_10distinctobj_surf_agent) +base_10simobj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10simobj, + n_eval_epochs=len(test_rotations_all), + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=SIMILAR_OBJECTS), + object_init_sampler=PredefinedObjectInitializer(rotations=test_rotations_all), + ), +) + +randrot_noise_10simobj_surf_agent = copy.deepcopy( + randrot_noise_10distinctobj_surf_agent +) +randrot_noise_10simobj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10simobj, + n_eval_epochs=10, # number of random rotations to test for each object + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=SIMILAR_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +randrot_noise_10simobj_dist_agent = copy.deepcopy( + randrot_noise_10distinctobj_dist_agent +) +randrot_noise_10simobj_dist_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_10simobj, + n_eval_epochs=10, # number of random rotations to test for each object + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=SIMILAR_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +randomrot_rawnoise_10distinctobj_surf_agent = copy.deepcopy( + randrot_noise_10distinctobj_surf_agent +) +randomrot_rawnoise_10distinctobj_surf_agent.update( + dataset_args=NoisySurfaceViewFinderMountHabitatDatasetArgs(), +) + +# Experiment with multiple (distractor objects) +base_10multi_distinctobj_dist_agent = copy.deepcopy( + base_config_10distinctobj_dist_agent +) +base_10multi_distinctobj_dist_agent.update( + # Agent is farther from object and takes larger steps to increase chance of + # landing on other objects; uses hypothesis-testing policy (which may also cause + # it to land on other objects) + monty_config=PatchAndViewFartherAwaySOTAMontyConfig( + learning_module_configs=lower_max_nneighbors_1lm_config, + monty_args=MontyArgs(min_eval_steps=min_eval_steps), + ), + eval_dataloader_args=EnvironmentDataloaderMultiObjectArgs( + object_names=dict( + targets_list=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + source_object_list=DISTINCT_OBJECTS, + num_distractors=10, # Number of other objects added to the environment + ), + object_init_sampler=PredefinedObjectInitializer(rotations=test_rotations_all), + ), +) + +# ----- Learning Unsupervised ----- + +default_lfs_lm = dict( + learning_module_0=dict( + learning_module_class=EvidenceGraphLM, + learning_module_args=dict( + max_match_distance=0.01, + tolerances=default_tolerances, + feature_weights=default_feature_weights, + # Higher threshold to avoid too many false positives during the first + # episodes. In the future we may consider some kind of learning schedule + x_percent_threshold=50, + graph_delta_thresholds=dict( + patch=dict( + distance=0.01, + pose_vectors=[np.pi / 8, np.pi * 2, np.pi * 2], + principal_curvatures_log=[1.0, 1.0], + hsv=[0.1, 1, 1], + ) + ), + # Since we have 100 min steps we want these steps to have been consistent + # with the mlh. If we keep this value at its default (1) it often happens + # that the episode just terminates once min steps is reached. Again, we + # try to avoid too many false positive in the first epochs. + object_evidence_threshold=100, + # Also the symmetry evidence increments a lot after 100 steps and easily + # reaches the default required evidence. Again, these are temporary fixes + # and we will probably want some more stable long term solutions. + required_symmetry_evidence=20, + max_nneighbors=5, + ), + ) +) + +# NOTE: Using the MotorSystemConfigCurvatureInformedSurface does not work so well +# in this setting and currently leads to more confused objects. + +surf_agent_unsupervised_10distinctobj = copy.deepcopy( + base_config_10distinctobj_dist_agent +) +surf_agent_unsupervised_10distinctobj.update( + experiment_args=ExperimentArgs( + do_eval=False, + n_train_epochs=10, + max_train_steps=4000, + max_total_steps=4000, + ), + logging_config=CSVLoggingConfig(python_log_level="INFO"), + monty_config=SurfaceAndViewMontyConfig( + monty_args=MontyArgs(num_exploratory_steps=1000, min_train_steps=100), + learning_module_configs=default_lfs_lm, + ), + dataset_args=SurfaceViewFinderMountHabitatDatasetArgs(), + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=DISTINCT_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +surf_agent_unsupervised_10distinctobj_noise = copy.deepcopy( + surf_agent_unsupervised_10distinctobj +) +surf_agent_unsupervised_10distinctobj_noise.update( + monty_config=SurfaceAndViewMontyConfig( + monty_args=MontyArgs(num_exploratory_steps=1000, min_train_steps=100), + sensor_module_configs=dict( + sensor_module_0=default_all_noisy_surf_agent_sensor_module, + sensor_module_1=dict( + sensor_module_class=DetailedLoggingSM, + sensor_module_args=dict( + sensor_module_id="view_finder", + save_raw_obs=True, + ), + ), + ), + learning_module_configs=default_lfs_lm, + ) +) + +surf_agent_unsupervised_10simobj = copy.deepcopy(surf_agent_unsupervised_10distinctobj) +surf_agent_unsupervised_10simobj.update( + train_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx(0, 10, object_list=SIMILAR_OBJECTS), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +# --------- Long Runs ---------------- + +base_77obj_dist_agent = copy.deepcopy(base_config_10distinctobj_dist_agent) +base_77obj_dist_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_1lm_77obj, + n_eval_epochs=len(test_rotations_3), + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, + 77, + ), + object_init_sampler=PredefinedObjectInitializer(rotations=test_rotations_3), + ), +) + +base_77obj_surf_agent = copy.deepcopy(base_config_10distinctobj_surf_agent) +base_77obj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_1lm_77obj, + n_eval_epochs=len(test_rotations_3), + max_total_steps=5000, + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, + 77, + ), + object_init_sampler=PredefinedObjectInitializer(rotations=test_rotations_3), + ), +) + +randrot_noise_77obj_surf_agent = copy.deepcopy(randrot_noise_10distinctobj_surf_agent) +randrot_noise_77obj_surf_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_1lm_77obj, + n_eval_epochs=3, + max_total_steps=5000, + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, + 77, + ), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +randrot_noise_77obj_dist_agent = copy.deepcopy(randrot_noise_10distinctobj_dist_agent) +randrot_noise_77obj_dist_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_1lm_77obj, + n_eval_epochs=3, + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, + 77, + ), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +randrot_noise_77obj_5lms_dist_agent = copy.deepcopy( + randrot_noise_10distinctobj_5lms_dist_agent +) +randrot_noise_77obj_5lms_dist_agent.update( + experiment_args=EvalExperimentArgs( + model_name_or_path=model_path_5lms_77obj, + n_eval_epochs=1, + min_lms_match=3, + ), + eval_dataloader_args=EnvironmentDataloaderPerObjectArgs( + object_names=get_object_names_by_idx( + 0, + 77, + ), + object_init_sampler=RandomRotationObjectInitializer(), + ), +) + +CONFIGS = dict( + base_config_10distinctobj_dist_agent=base_config_10distinctobj_dist_agent, + base_config_10distinctobj_surf_agent=base_config_10distinctobj_surf_agent, + randrot_noise_10distinctobj_dist_agent=randrot_noise_10distinctobj_dist_agent, + randrot_noise_10distinctobj_dist_on_distm=randrot_noise_10distinctobj_dist_on_distm, + randrot_noise_10distinctobj_surf_agent=randrot_noise_10distinctobj_surf_agent, + randrot_10distinctobj_surf_agent=randrot_10distinctobj_surf_agent, + randrot_noise_10distinctobj_5lms_dist_agent=randrot_noise_10distinctobj_5lms_dist_agent, + base_10simobj_surf_agent=base_10simobj_surf_agent, + randrot_noise_10simobj_surf_agent=randrot_noise_10simobj_surf_agent, + randrot_noise_10simobj_dist_agent=randrot_noise_10simobj_dist_agent, + randomrot_rawnoise_10distinctobj_surf_agent=randomrot_rawnoise_10distinctobj_surf_agent, + base_10multi_distinctobj_dist_agent=base_10multi_distinctobj_dist_agent, + # ------------- Not yet evaluated ------------- + surf_agent_unsupervised_10distinctobj=surf_agent_unsupervised_10distinctobj, + surf_agent_unsupervised_10distinctobj_noise=surf_agent_unsupervised_10distinctobj_noise, + surf_agent_unsupervised_10simobj=surf_agent_unsupervised_10simobj, + # ------------- long runs with all objects ------------- + base_77obj_dist_agent=base_77obj_dist_agent, + base_77obj_surf_agent=base_77obj_surf_agent, + randrot_noise_77obj_surf_agent=randrot_noise_77obj_surf_agent, + randrot_noise_77obj_dist_agent=randrot_noise_77obj_dist_agent, + randrot_noise_77obj_5lms_dist_agent=randrot_noise_77obj_5lms_dist_agent, +) diff --git a/floppy/frameworks/__init__.py b/floppy/frameworks/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/floppy/frameworks/models/evidence_matching.py b/floppy/frameworks/models/evidence_matching.py new file mode 100644 index 0000000..ae605fa --- /dev/null +++ b/floppy/frameworks/models/evidence_matching.py @@ -0,0 +1,316 @@ +from scipy.spatial import KDTree +import numpy as np +import logging +from collections import defaultdict +from typing import Dict, List, Tuple, Optional, Any +from tbp.monty.frameworks.models.evidence_matching import ( + EvidenceGraphLM, +) +from frameworks.models.goal_state_generation import ( + FlopCountingEvidenceGoalStateGenerator, +) +from tbp.monty.frameworks.utils.graph_matching_utils import ( + add_pose_features_to_tolerances, + get_custom_distances, + get_initial_possible_poses, + get_relevant_curvature, + get_scaled_evidences, +) +from tbp.monty.frameworks.utils.spatial_arithmetics import ( + align_multiple_orthonormal_vectors, + align_orthonormal_vectors, + get_angles_for_all_hypotheses, + get_more_directions_in_plane, + rotate_pose_dependent_features, +) + + +class FlopCountingEvidenceGraphLM(EvidenceGraphLM): + """Extension of EvidenceGraphLM that counts FLOPs for KDTree operations.""" + + def __init__( + self, + max_match_distance, + tolerances, + feature_weights, + feature_evidence_increment=1, + max_nneighbors=3, + initial_possible_poses="informed", + evidence_update_threshold="all", + vote_evidence_threshold=0.8, + past_weight=1, + present_weight=1, + vote_weight=1, + object_evidence_threshold=1, + x_percent_threshold=10, + path_similarity_threshold=0.1, + pose_similarity_threshold=0.35, + required_symmetry_evidence=5, + graph_delta_thresholds=None, + max_graph_size=0.3, + max_nodes_per_graph=2000, + num_model_voxels_per_dim=50, + use_multithreading=True, + gsg_class=FlopCountingEvidenceGoalStateGenerator, + gsg_args=None, + *args, + **kwargs, + ): + # Call parent's __init__ with all parameters + super().__init__( + max_match_distance=max_match_distance, + tolerances=tolerances, + feature_weights=feature_weights, + feature_evidence_increment=feature_evidence_increment, + max_nneighbors=max_nneighbors, + initial_possible_poses=initial_possible_poses, + evidence_update_threshold=evidence_update_threshold, + vote_evidence_threshold=vote_evidence_threshold, + past_weight=past_weight, + present_weight=present_weight, + vote_weight=vote_weight, + object_evidence_threshold=object_evidence_threshold, + x_percent_threshold=x_percent_threshold, + path_similarity_threshold=path_similarity_threshold, + pose_similarity_threshold=pose_similarity_threshold, + required_symmetry_evidence=required_symmetry_evidence, + graph_delta_thresholds=graph_delta_thresholds, + max_graph_size=max_graph_size, + max_nodes_per_graph=max_nodes_per_graph, + num_model_voxels_per_dim=num_model_voxels_per_dim, + use_multithreading=use_multithreading, + gsg_class=gsg_class, + gsg_args=gsg_args, + *args, + **kwargs, + ) + self.flop_counter = None + + def _update_evidence_with_vote(self, state_votes, graph_id): + """Count FLOPs for KDTree operations during vote processing.""" + # Extract vote information + graph_location_vote = np.zeros((len(state_votes), 3)) + vote_evidences = np.zeros(len(state_votes)) + for n, vote in enumerate(state_votes): + graph_location_vote[n] = vote.location + vote_evidences[n] = vote.confidence + + # Execute KDTree query + vote_location_tree = KDTree( + graph_location_vote, + leafsize=40, + ) + vote_nn = 3 # TODO: Make this a parameter? + if graph_location_vote.shape[0] < vote_nn: + vote_nn = graph_location_vote.shape[0] + + # Account for FLOPs for KDTree Construction + num_reference_points = len(graph_location_vote) + dim1 = self.possible_locations[graph_id].shape[1] + kdtree_flops = int(num_reference_points * np.log2(num_reference_points) * dim1) + + (radius_node_dists, radius_node_ids) = vote_location_tree.query( + self.possible_locations[graph_id], + k=vote_nn, + p=2, + workers=1, + ) + + # Account for FLOPs for KDTree query + num_search_points = len(self.possible_locations[graph_id]) + num_reference_points = len(graph_location_vote) + + # Tree Traversal FLOPs + # Depth of tree is log2(num_reference_points) for balanced tree + dim1 = self.possible_locations[graph_id].shape[1] + traversal_flops = num_search_points * dim1 * np.log2(num_reference_points) + # FLOPs for distance + num_examined_points = int(np.log2(num_reference_points)) + distance_flops = ( + num_search_points * num_examined_points * (3 * dim1 + dim1 + 1) + ) # dim1*(3 ops per dim) + dim1 additions + 1 sqrt + # Heap operations + heap_flops = num_search_points * num_examined_points * np.log2(max(vote_nn, 1)) + + # FLOPs for bounding box check + bounding_box_flops = num_search_points * num_examined_points * dim1 + total_flops = int( + kdtree_flops + + traversal_flops + + distance_flops + + heap_flops + + bounding_box_flops + ) + if self.flop_counter is not None: + self.flop_counter.add_flops(total_flops) + + # Remainder of code + if vote_nn == 1: + radius_node_dists = np.expand_dims(radius_node_dists, axis=1) + radius_node_ids = np.expand_dims(radius_node_ids, axis=1) + + radius_evidences = vote_evidences[radius_node_ids] + node_distance_weights = self._get_node_distance_weights(radius_node_dists) + too_far_away = node_distance_weights <= 0 + all_radius_evidence = np.ma.array(radius_evidences, mask=too_far_away) + distance_weighted_vote_evidence = np.ma.max(all_radius_evidence, axis=1) + + # Update evidence based on weights + if self.past_weight + self.present_weight == 1: + self.evidence[graph_id] = np.ma.average( + [self.evidence[graph_id], distance_weighted_vote_evidence], + weights=[1, self.vote_weight], + axis=0, + ) + else: + self.evidence[graph_id] = np.ma.sum( + [ + self.evidence[graph_id], + distance_weighted_vote_evidence * self.vote_weight, + ], + axis=0, + ) + + def _calculate_evidence_for_new_locations( + self, + graph_id, + input_channel, + search_locations, + features, + hyp_ids_to_test, + ): + """Use search locations, sensed features and graph model to calculate evidence. + + First, the search locations are used to find the nearest nodes in the graph + model. Then we calculate the error between the stored pose features and the + sensed ones. Additionally we look at whether the non-pose features match at the + neigboring nodes. Everything is weighted by the nodes distance from the search + location. + If there are no nodes in the search radius (max_match_distance), evidence = -1. + + We do this for every incoming input channel and its features if they are stored + in the graph and take the average over the evidence from all input channels. + + Returns: + The location evidence. + """ + logging.debug( + f"Calculating evidence for {graph_id} using input from " f"{input_channel}" + ) + + pose_transformed_features = rotate_pose_dependent_features( + features[input_channel], + self.possible_poses[graph_id][hyp_ids_to_test], + ) + + # Get max_nneighbors nearest nodes to search locations. + nearest_node_ids = self.get_graph( + graph_id, input_channel + ).find_nearest_neighbors( + search_locations, + num_neighbors=self.max_nneighbors, + ) + + # def find_nearest_neighbors(): + # (distances, nearest_node_ids) = self._location_tree.query( + # search_locations, + # k=num_neighbors, + # p=2, # eucledian distance + # workers=1, # using more than 1 worker slows down run on lambda. + # ) + + num_search_points = len(search_locations) + num_reference_points = len( + self.graph_memory.get_locations_in_graph(graph_id, input_channel) + ) + dim1 = search_locations.shape[1] + traversal_flops = num_search_points * dim1 * np.log2(num_reference_points) + num_examined_points = int(np.log2(num_reference_points)) + distance_flops = ( + num_search_points * num_examined_points * (3 * dim1 + dim1 + 1) + ) # dim1*(3 ops per dim) + dim1 additions + 1 sqrt + heap_flops = ( + num_search_points * num_examined_points * np.log2(self.max_nneighbors) + ) + bounding_box_flops = num_search_points * num_examined_points * dim1 + total_flops = int( + traversal_flops + distance_flops + heap_flops + bounding_box_flops + ) + if self.flop_counter is not None: + self.flop_counter.add_flops(total_flops) + + if self.max_nneighbors == 1: + nearest_node_ids = np.expand_dims(nearest_node_ids, axis=1) + + nearest_node_locs = self.graph_memory.get_locations_in_graph( + graph_id, input_channel + )[nearest_node_ids] + max_abs_curvature = get_relevant_curvature(features[input_channel]) + custom_nearest_node_dists = get_custom_distances( + nearest_node_locs, + search_locations, + pose_transformed_features["pose_vectors"][:, 0], + max_abs_curvature, + ) + + # shape=(H, K) + node_distance_weights = self._get_node_distance_weights( + custom_nearest_node_dists + ) + # Get IDs where custom_nearest_node_dists > max_match_distance + mask = node_distance_weights <= 0 + + new_pos_features = self.graph_memory.get_features_at_node( + graph_id, + input_channel, + nearest_node_ids, + feature_keys=["pose_vectors", "pose_fully_defined"], + ) + # Calculate the pose error for each hypothesis + # shape=(H, K) + radius_evidence = self._get_pose_evidence_matrix( + pose_transformed_features, + new_pos_features, + input_channel, + node_distance_weights, + ) + # Set the evidences which are too far away to -1 + radius_evidence[mask] = -1 + # If a node is too far away, weight the negative evidence fully (*1). This + # only comes into play if there are no nearby nodes in the radius, then we + # want an evidence of -1 for this hypothesis. + # NOTE: Currently we don't weight the evidence by distance so this doesn't + # matter. + node_distance_weights[mask] = 1 + + # If no feature weights are provided besides the ones for point_normal + # and curvature_directions we don't need to calculate feature evidence. + if self.use_features_for_matching[input_channel]: + # add evidence if features match + node_feature_evidence = self._calculate_feature_evidence_for_all_nodes( + features, input_channel, graph_id + ) + hypothesis_radius_feature_evidence = node_feature_evidence[nearest_node_ids] + # Set feature evidence of nearest neighbors that are too far away to 0 + hypothesis_radius_feature_evidence[mask] = 0 + # Take the maximum feature evidence out of the nearest neighbors in the + # search radius and weighted by its distance to the search location. + # Evidence will be in [0, 1] and is only 1 if all features match + # perfectly and the node is at the search location. + radius_evidence = ( + radius_evidence + + hypothesis_radius_feature_evidence * self.feature_evidence_increment + ) + # We take the maximum to be better able to deal with parts of the model where + # features change quickly and we may have noisy location information. This way + # we check if we can find a good match of pose features within the search + # radius. It doesn't matter if there are also points stored nearby in the model + # that are not a good match. + # Removing the comment weights the evidence by the nodes distance from the + # search location. However, epirically this did not seem to help. + # shape=(H,) + location_evidence = np.max( + radius_evidence, # * node_distance_weights, + axis=1, + ) + return location_evidence \ No newline at end of file diff --git a/floppy/frameworks/models/goal_state_generation.py b/floppy/frameworks/models/goal_state_generation.py new file mode 100644 index 0000000..f0d608a --- /dev/null +++ b/floppy/frameworks/models/goal_state_generation.py @@ -0,0 +1,82 @@ +from tbp.monty.frameworks.models.goal_state_generation import EvidenceGoalStateGenerator +import numpy as np +import logging + + +class FlopCountingEvidenceGoalStateGenerator(EvidenceGoalStateGenerator): + """Extension of EvidenceGoalStateGenerator that counts FLOPs for KDTree operations.""" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.flop_counter = None + + def _compute_graph_mismatch(self): + """Override to count FLOPs during graph mismatch computation. + + Similar to parent method but adds FLOP counting for KDTree operations. + """ + logging.debug("Proposing an evaluation location based on graph mismatch") + + top_id, second_id = self.parent_lm.get_top_two_mlh_ids() + + top_mlh = self.parent_lm.get_mlh_for_object(top_id) + second_mlh_object = self.parent_lm.get_mlh_for_object(second_id) + + top_mlh_graph = self.parent_lm.get_graph(top_id, input_channel="first").pos + + if self.focus_on_pose: + second_id = top_id + _, second_mlh = self.parent_lm.get_top_two_pose_hypotheses_for_graph_id( + top_id + ) + else: + second_mlh = second_mlh_object + + # Transform graph coordinates as in parent method + rotated_graph = top_mlh["rotation"].inv().apply(top_mlh_graph) + current_mlh_location = top_mlh["rotation"].inv().apply(top_mlh["location"]) + top_mlh_graph = rotated_graph - current_mlh_location + top_mlh_graph = ( + second_mlh["rotation"].apply(top_mlh_graph) + second_mlh["location"] + ) + # Perform KDTree search + radius_node_dists = self.parent_lm.get_graph( + second_id, input_channel="first" + ).find_nearest_neighbors( + top_mlh_graph, + num_neighbors=1, + return_distance=True, + ) + + # Calculate FLOPs for KDTree operations + num_search_points = len(top_mlh_graph) + num_reference_points = len( + self.parent_lm.get_graph(second_id, input_channel="first").pos + ) + + # Tree Traversal FLOPs + dim1 = top_mlh_graph.shape[1] + traversal_flops = num_search_points * dim1 * np.log2(num_reference_points) + # FLOPs for distance + num_examined_points = int(np.log2(num_reference_points)) + distance_flops = ( + num_search_points * num_examined_points * (3 * dim1 + dim1 + 1) + ) # dim1*(3 ops per dim) + dim1 additions + 1 sqrt + # Heap operations + heap_flops = 0 # because num_neighbors is 1 + # FLOPs for bounding box check + bounding_box_flops = num_search_points * num_examined_points * dim1 + total_flops = int( + traversal_flops + distance_flops + heap_flops + bounding_box_flops + ) + + # Add FLOPs to counter if available + if self.flop_counter is not None: + self.flop_counter.add_flops(total_flops) + + target_loc_id = np.argmax(radius_node_dists) + target_loc_separation = np.max(radius_node_dists) + + self.prev_top_mlhs = [top_mlh, second_mlh_object] + + return target_loc_id, target_loc_separation diff --git a/floppy/frameworks/models/object_model.py b/floppy/frameworks/models/object_model.py new file mode 100644 index 0000000..9eb211f --- /dev/null +++ b/floppy/frameworks/models/object_model.py @@ -0,0 +1,86 @@ +import numpy as np +import torch +import torch_geometric +from torch_geometric.data import Data + +from tbp.monty.frameworks.models.object_model import GraphObjectModel +from tbp.monty.frameworks.models.object_model import ( + get_correct_k_n, + remove_close_points, +) + + +class FlopCountingObjectModel(GraphObjectModel): + """Object model that counts FLOPs for KDTree operations.""" + + def __init__(self, *args, **kwargs): + super().__init__(*args, **kwargs) + self.flop_counter = None + + def _build_adjacency_graph( + self, locations, features, k_n, graph_delta_thresholds, old_graph_index + ): + locations_reduced, clean_ids = remove_close_points( + np.array(locations), features, graph_delta_thresholds, old_graph_index + ) + num_nodes = locations_reduced.shape[0] + node_features = np.linspace(0, num_nodes - 1, num_nodes).reshape((num_nodes, 1)) + feature_mapping = dict() + feature_mapping["node_ids"] = [0, 1] + + for feature_id in features.keys(): + feats = np.array([features[feature_id][i] for i in clean_ids]) + if len(feats.shape) == 1: + feats = feats.reshape((feats.shape[0], 1)) + + feature_mapping[feature_id] = [ + node_features.shape[1], + node_features.shape[1] + feats.shape[1], + ] + node_features = np.column_stack((node_features, feats)) + + if feature_id == "pose_vectors": + norm = torch.tensor(feats[:, :3], dtype=torch.float) + + assert np.all( + locations[:old_graph_index] == locations_reduced[:old_graph_index] + ), "Old graph points shouldn't change" + + x = torch.tensor(node_features, dtype=torch.float) + pos = torch.tensor(locations_reduced, dtype=torch.float) + + graph = Data(x=x, pos=pos, norm=norm, feature_mapping=feature_mapping) + + if k_n is not None: + k_n = get_correct_k_n(k_n, num_nodes) + + scipy_graph = kneighbors_graph( + locations_reduced, n_neighbors=k_n, include_self=False + ) + # Count FLOPs for kneighbors_graph calculation + n = len(locations_reduced) + # Calculate distances from each point to all others (n points * (n-1) other points * 9 FLOPs per distance) + distance_flops = n * (n - 1) * 9 + # Add approximate cost for partial sorting to find k nearest neighbors + # Using O(n log k) complexity for each point's partial sort + if k_n > 0: + sorting_flops = n * (n - 1) * np.log2(k_n) + if self.flop_counter is not None: + self.flop_counter.add_flops(distance_flops + sorting_flops) + + scipygraph = torch_geometric.utils.from_scipy_sparse_matrix(scipy_graph) + edge_index = scipygraph[0] + + displacements = [] + for e, edge_start in enumerate(edge_index[0]): + edge_end = edge_index[1][e] + displacements.append( + locations_reduced[edge_end] - locations_reduced[edge_start] + ) + + edge_attr = torch.tensor(np.array(displacements), dtype=torch.float) + + graph.edge_index = edge_index + graph.edge_attr = edge_attr + + return graph diff --git a/floppy/frameworks/run.py b/floppy/frameworks/run.py new file mode 100644 index 0000000..9001167 --- /dev/null +++ b/floppy/frameworks/run.py @@ -0,0 +1,129 @@ +# Copyright 2022-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +import os +import logging +import time +from tbp.monty.frameworks.run import ( + merge_args, + print_config, + run, + create_cmd_parser, + config_to_dict, +) +from typing import Dict, Any +from frameworks.models.evidence_matching import FlopCountingEvidenceGraphLM +from frameworks.models.goal_state_generation import ( + FlopCountingEvidenceGoalStateGenerator, +) +from src.floppy.counting.tracer import MontyFlopTracer + +def wrap_experiment_with_flops(experiment_cls, run_name): + """Wraps both Monty and Experiment classes to add FLOP tracking.""" + original_setup = experiment_cls.setup_experiment + + def wrapped_setup(self, config): + """Wrap the setup_experiment to initialize counters first.""" + # Initialize counters before doing anything else + self.init_counters() + + modified_config = config.copy() + # Update config to replace EvidenceGraphLM with FlopCountingEvidenceGraphLM + for lm_key in modified_config["monty_config"]["learning_module_configs"]: + lm_config = modified_config["monty_config"]["learning_module_configs"][ + lm_key + ] + lm_config["learning_module_class"] = FlopCountingEvidenceGraphLM + lm_config["learning_module_args"]["gsg_class"] = ( + FlopCountingEvidenceGoalStateGenerator + ) + + # Call original setup + original_setup(self, modified_config) + + flop_tracker = MontyFlopTracer( + experiment_name=run_name, + monty_instance=self.model, + experiment_instance=self, + train_dataloader_instance=self.dataloader, + eval_dataloader_instance=self.eval_dataloader, + motor_system_instance=self.model.motor_system, + ) + one_true_flop_counter = flop_tracker.flop_counter + for lm in self.model.learning_modules: + if isinstance(lm, FlopCountingEvidenceGraphLM): + lm.flop_counter = one_true_flop_counter + if hasattr(lm, "gsg") and isinstance( + lm.gsg, FlopCountingEvidenceGoalStateGenerator + ): + lm.gsg.flop_counter = one_true_flop_counter + self.flop_tracker = flop_tracker + # Wrap the experiment's setup and Monty's init + experiment_cls.setup_experiment = wrapped_setup + + return experiment_cls + + +def run_with_flops(exp_config: Dict[str, Any]): + """Runs an experiment with FLOP tracking by modifying both classes.""" + original_experiment_class = exp_config.get("experiment_class") + + if original_experiment_class is None: + raise ValueError("No experiment_class found in exp_config") + + run_name = exp_config["logging_config"]["run_name"] + wrapped_experiment = wrap_experiment_with_flops(original_experiment_class, run_name) + + # Update config with wrapped classes + exp_config["experiment_class"] = wrapped_experiment + + # Run with the modified config + result = run(exp_config) + return result + + +def flop_main(all_configs, experiments=None): + """Main function that runs experiments with FLOP counting enabled.""" + cmd_args = None + if not experiments: + cmd_parser = create_cmd_parser(all_configs=all_configs) + cmd_args = cmd_parser.parse_args() + experiments = cmd_args.experiments + if cmd_args.quiet_habitat_logs: + os.environ["MAGNUM_LOG"] = "quiet" + os.environ["HABITAT_SIM_LOG"] = "quiet" + + for experiment in experiments: + exp = all_configs[experiment] + exp_config = merge_args(exp, cmd_args) + exp_config = config_to_dict(exp_config) + + # Update run_name and output dir with experiment name + if not exp_config["logging_config"]["run_name"]: + exp_config["logging_config"]["run_name"] = experiment + exp_config["logging_config"]["output_dir"] = os.path.join( + exp_config["logging_config"]["output_dir"], + exp_config["logging_config"]["run_name"], + ) + + # If we are not running in parallel, this should always be False + exp_config["logging_config"]["log_parallel_wandb"] = False + + # Print config if requested + if cmd_args is not None and cmd_args.print_config: + print_config(exp_config) + continue + + # Create output directory + os.makedirs(exp_config["logging_config"]["output_dir"], exist_ok=True) + + # Run the experiment with FLOP tracking + start_time = time.time() + run_with_flops(exp_config) + logging.info(f"Done running {experiment} in {time.time() - start_time} seconds") diff --git a/floppy/run_flop_counter.py b/floppy/run_flop_counter.py new file mode 100644 index 0000000..dd3aa6e --- /dev/null +++ b/floppy/run_flop_counter.py @@ -0,0 +1,20 @@ +# Copyright 2022-2024 Numenta Inc. +# +# Copyright may exist in Contributors' modifications +# and/or contributions to the work. +# +# Use of this source code is governed by the MIT +# license that can be found in the LICENSE file or at +# https://opensource.org/licenses/MIT. + +from tbp.monty.frameworks.run_env import setup_env + +setup_env() + +# Load all experiment configurations from local project +from configs import CONFIGS # noqa: E402 + +from frameworks.run import flop_main # noqa: E402 + +if __name__ == "__main__": + flop_main(all_configs=CONFIGS) diff --git a/floppy/run_static_analysis.py b/floppy/run_static_analysis.py new file mode 100644 index 0000000..9ff688f --- /dev/null +++ b/floppy/run_static_analysis.py @@ -0,0 +1,49 @@ +import argparse +from pathlib import Path +from src.floppy.analysis.analyzer import FlopAnalyzer + + +def main(input_dir, output_dir=None): + """ + Run static analysis on Python files in a specified directory. + Results are saved to a CSV file in the output directory. + """ + + if output_dir is None: + output_dir = str( + Path("~/tbp/monty_lab/floppy/results").expanduser() / "static_analysis" + ) + + analyzer = FlopAnalyzer() + + try: + input_dir = Path(input_dir).expanduser().resolve() + # Analyze a directory of Python files + results = analyzer.analyze_directory(input_dir) + + # Save results to CSV + output_file = analyzer.save_results(results, output_dir) + + print(f"\nDetailed results saved to: {output_file}") + + except Exception as e: + print(f"Error during analysis: {str(e)}") + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Run static analysis on Python files.") + parser.add_argument( + "--directory", + "-d", + default="~/tbp/tbp.monty/src", + help="Directory containing Python files to analyze", + ) + parser.add_argument( + "--output", + "-o", + default=None, + help="Output directory for results (if not specified, uses ~/tbp/monty_lab/floppy/results)", + ) + + args = parser.parse_args() + main(args.directory, args.output) diff --git a/floppy/src/floppy/__init__.py b/floppy/src/floppy/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/floppy/src/floppy/analysis/__init__.py b/floppy/src/floppy/analysis/__init__.py new file mode 100644 index 0000000..6800e0b --- /dev/null +++ b/floppy/src/floppy/analysis/__init__.py @@ -0,0 +1,4 @@ +from .analyzer import FlopAnalyzer +from .exceptions import FileAnalysisError + +__all__ = ["FlopAnalyzer", "FileAnalysisError"] diff --git a/floppy/src/floppy/analysis/analyzer.py b/floppy/src/floppy/analysis/analyzer.py new file mode 100644 index 0000000..a7ec082 --- /dev/null +++ b/floppy/src/floppy/analysis/analyzer.py @@ -0,0 +1,233 @@ +import ast +from pathlib import Path +from datetime import datetime +from typing import Dict, List, Any +import pandas as pd +from .visitors.numpy_visitor import NumpyCallVisitor +from .visitors.scipy_visitor import ScipyCallVisitor +from .visitors.sklearn_visitor import SklearnCallVisitor +from .exceptions import FileAnalysisError + + +class FlopAnalyzer: + """Main analyzer class for finding and analyzing FLOP operations in Python code.""" + + def __init__(self): + self.analysis_results: Dict[str, Dict] = {} + self.numpy_visitor = NumpyCallVisitor() + self.scipy_visitor = ScipyCallVisitor() + self.sklearn_visitor = SklearnCallVisitor() + + def analyze_file(self, filepath: str) -> Dict[str, Any]: + """Analyze a single Python file for FLOP operations. + + Args: + filepath: Path to the Python file to analyze + + Returns: + Dict containing analysis results with keys: + - numpy_calls: List of NumPy function calls + - scipy_calls: List of SciPy function calls + - sklearn_calls: List of scikit-learn function calls + + Raises: + FileAnalysisError: If there's an error reading or parsing the file + """ + try: + with open(filepath, "r") as f: + tree = ast.parse(f.read()) + except (IOError, SyntaxError) as e: + raise FileAnalysisError(f"Error reading/parsing {filepath}: {str(e)}") + + # Reset visitors + self.numpy_visitor = NumpyCallVisitor() + self.scipy_visitor = ScipyCallVisitor() + self.sklearn_visitor = SklearnCallVisitor() + + # Visit the AST with each visitor + self.numpy_visitor.visit(tree) + self.scipy_visitor.visit(tree) + self.sklearn_visitor.visit(tree) + + # Format calls into a consistent structure + numpy_calls = [ + { + "module": "numpy", + "type": t, + "function": n, + "line": l, + } + for t, n, l in self.numpy_visitor.calls + ] + + scipy_calls = [ + { + "module": "scipy", + "type": t, + "function": n, + "line": l, + } + for t, n, l in self.scipy_visitor.calls + ] + + sklearn_calls = [ + { + "module": "sklearn", + "type": t, + "function": n, + "line": l, + } + for t, n, l in self.sklearn_visitor.calls + ] + + results = { + "numpy_calls": numpy_calls, + "scipy_calls": scipy_calls, + "sklearn_calls": sklearn_calls, + "imports": self._collect_imports(), + } + + self.analysis_results[filepath] = results + return results + + def _collect_imports(self) -> List[Dict]: + """Collect all imports from the visitors.""" + imports = [] + + # Collect NumPy imports + for name, module in self.numpy_visitor.imports.items(): + imports.append({"module": "numpy", "name": name}) + + # Collect SciPy imports + for name, module in self.scipy_visitor.imports.items(): + imports.append({"module": "scipy", "name": name}) + + # Collect scikit-learn imports + for name, module in self.sklearn_visitor.imports.items(): + imports.append({"module": "sklearn", "name": name}) + + return imports + + def analyze_directory( + self, directory: str, recursive: bool = True + ) -> Dict[str, Any]: + """Analyze all Python files in a directory. + + Args: + directory: Path to directory to analyze + recursive: Whether to recursively analyze subdirectories + + Returns: + Dict containing: + - files: Dict mapping filenames to their analysis results + - total_stats: Aggregated statistics across all files + """ + path = Path(directory) + if not path.exists(): + raise FileNotFoundError(f"Directory {directory} does not exist") + + pattern = "**/*.py" if recursive else "*.py" + results = { + "files": {}, + "total_stats": { + "numpy_calls": 0, + "scipy_calls": 0, + "sklearn_calls": 0, + "total_files": 0, + }, + } + + for py_file in path.glob(pattern): + try: + file_results = self.analyze_file(str(py_file)) + results["files"][str(py_file)] = file_results + + # Update totals + results["total_stats"]["numpy_calls"] += len( + file_results["numpy_calls"] + ) + results["total_stats"]["scipy_calls"] += len( + file_results["scipy_calls"] + ) + results["total_stats"]["sklearn_calls"] += len( + file_results["sklearn_calls"] + ) + results["total_stats"]["total_files"] += 1 + + except FileAnalysisError as e: + print(f"Warning: {str(e)}") + continue + + return results + + def save_results(self, results: Dict[str, Any], output_dir: str) -> str: + """Save analysis results to CSV files. + + Args: + results: Analysis results from analyze_directory() + output_dir: Directory to save results in + + Returns: + Path to the saved results file + """ + timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") + output_path = Path(output_dir) + output_path.mkdir(parents=True, exist_ok=True) + + rows = [] + for filename, analysis in results["files"].items(): + # Add operations + self._add_operation_rows(rows, filename, analysis) + # Add imports + self._add_import_rows(rows, filename, analysis) + + if rows: + df = pd.DataFrame(rows) + output_file = output_path / f"flop_analysis_{timestamp}.csv" + df.to_csv(output_file, index=False) + return str(output_file) + + return "" + + def _add_operation_rows( + self, rows: List[Dict], filename: str, analysis: Dict + ) -> None: + """Add rows for operations to the results DataFrame.""" + # Add all operations including library calls, assignments, and binary operations + for op_type in ["numpy_calls", "sklearn_calls", "scipy_calls"]: + for op in analysis[op_type]: + row = { + "filename": filename, + "operation_type": self._get_operation_type(op["type"]), + "module": op["module"], + "function": op["function"], + "line": op.get("line", ""), + } + rows.append(row) + + def _get_operation_type(self, type_str: str) -> str: + """Convert the operation type to a consistent category.""" + type_mapping = { + "direct": "function_call", + "attribute": "method_call", + "binary": "binary_operation", + "assign": "assignment", + } + return type_mapping.get(type_str, type_str) + + def _add_import_rows(self, rows: List[Dict], filename: str, analysis: Dict) -> None: + """Add rows for imports to the results DataFrame.""" + for lib_type in ["numpy_imports", "sklearn_imports", "scipy_imports"]: + if lib_type in analysis: + for import_info in analysis[lib_type]: + row = { + "filename": filename, + "import_type": import_info.get( + "type", "direct" + ), # direct, from, star + "module": import_info.get("module", ""), + "name": import_info.get("name", ""), + "alias": import_info.get("alias", ""), + "line": import_info.get("line", ""), + } + rows.append(row) diff --git a/floppy/src/floppy/analysis/exceptions.py b/floppy/src/floppy/analysis/exceptions.py new file mode 100644 index 0000000..a534c5b --- /dev/null +++ b/floppy/src/floppy/analysis/exceptions.py @@ -0,0 +1,4 @@ +class FileAnalysisError(Exception): + """Exception raised for errors during file analysis.""" + + pass diff --git a/floppy/src/floppy/analysis/visitors/__init__.py b/floppy/src/floppy/analysis/visitors/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/floppy/src/floppy/analysis/visitors/base_visitor.py b/floppy/src/floppy/analysis/visitors/base_visitor.py new file mode 100644 index 0000000..d7811e0 --- /dev/null +++ b/floppy/src/floppy/analysis/visitors/base_visitor.py @@ -0,0 +1,144 @@ +import ast + + +class BaseLibraryVisitor(ast.NodeVisitor): + """Base class for library-specific visitors.""" + + def __init__(self, library_name: str): + self.library_name = library_name + self.imports = {} # Track what names refer to the library + self.calls = set() # Using a set to avoid duplicates + self.variables = set() # Track variables holding library objects + self.star_imported = False # Track if library was star imported + + def visit_Import(self, node): + """Handle import statements.""" + for alias in node.names: + if alias.name.startswith(self.library_name): + self.imports[alias.asname or alias.name] = alias.name + self.generic_visit(node) + + def visit_ImportFrom(self, node): + """Handle from-import statements.""" + if node.module and node.module.startswith(self.library_name): + if len(node.names) == 1 and node.names[0].name == "*": + self.star_imported = True + print(f"Warning: '*' imports detected - some calls might be missed") + else: + for alias in node.names: + self.imports[alias.asname or alias.name] = ( + f"{node.module}.{alias.name}" + ) + self.generic_visit(node) + + def visit_Assign(self, node): + """Handle assignments.""" + # Handle multiple assignments + if isinstance(node.value, ast.Call) and self._is_library_call(node.value): + for target in node.targets: + if isinstance(target, ast.Name): + self.variables.add(target.id) + elif isinstance(target, ast.Tuple): + for elt in target.elts: + if isinstance(elt, ast.Name): + self.variables.add(elt.id) + + # Handle name assignments + elif isinstance(node.value, ast.Name): + if node.value.id in self.imports: + for target in node.targets: + if isinstance(target, ast.Name): + self.imports[target.id] = self.imports[node.value.id] + + # Handle submodule assignments + elif isinstance(node.value, ast.Attribute): + attr_chain = self._get_attribute_chain(node.value) + if attr_chain[0] in self.imports: + base_import = self.imports[attr_chain[0]] + full_import = f"{base_import}.{'.'.join(attr_chain[1:])}" + for target in node.targets: + if isinstance(target, ast.Name): + self.imports[target.id] = full_import + + self.generic_visit(node) + + def _is_library_variable(self, node): + """Check if node represents a library variable.""" + if isinstance(node, ast.Name): + return node.id in self.variables + return False + + def _is_library_call(self, node): + """Check if node represents a library function call.""" + if isinstance(node.func, ast.Name): + return node.func.id in self.imports or ( + self.star_imported and hasattr(node.func, "id") + ) + elif isinstance(node.func, ast.Attribute): + attr_chain = self._get_attribute_chain(node.func) + return attr_chain[0] in self.imports or attr_chain[0] in self.variables + return False + + def _get_attribute_chain(self, node): + """Get the full chain of attributes.""" + parts = [] + current = node + while isinstance(current, ast.Attribute): + parts.insert(0, current.attr) + current = current.value + if isinstance(current, ast.Name): + parts.insert(0, current.id) + return parts + + def _add_call(self, call_type: str, name: str, lineno: int): + """Add a call to the tracked calls set.""" + self.calls.add((call_type, name, lineno)) + + def visit_Call(self, node): + """Handle function calls.""" + # Handle direct calls + if isinstance(node.func, ast.Name): + if node.func.id in self.imports: + self._add_call("direct", self.imports[node.func.id], node.lineno) + elif self.star_imported: + self._add_call( + "direct", f"{self.library_name}.{node.func.id}", node.lineno + ) + + # Handle attribute calls and chains + elif isinstance(node.func, ast.Attribute): + current = node.func + method_chain = [] + + while isinstance(current, ast.Attribute): + method_chain.insert(0, current.attr) + current = current.value + + if isinstance(current, ast.Name): + base_name = current.id + if base_name in self.imports: + full_name = self.imports[base_name] + "." + ".".join(method_chain) + self._add_call("attribute", full_name, node.lineno) + elif base_name in self.variables: + full_name = f"{self.library_name}." + ".".join(method_chain) + self._add_call("attribute", full_name, node.lineno) + elif isinstance(current, ast.Call): + self.visit(current) + if method_chain: + self._add_call( + "attribute", + f"{self.library_name}." + ".".join(method_chain), + node.lineno, + ) + + # Visit arguments and keywords + for arg in node.args: + self.visit(arg) + for keyword in node.keywords: + self.visit(keyword.value) + + # Handle chained calls + if isinstance(node.func, ast.Attribute) and isinstance( + node.func.value, ast.Call + ): + self.visit(node.func.value) diff --git a/floppy/src/floppy/analysis/visitors/numpy_visitor.py b/floppy/src/floppy/analysis/visitors/numpy_visitor.py new file mode 100644 index 0000000..2dc8e92 --- /dev/null +++ b/floppy/src/floppy/analysis/visitors/numpy_visitor.py @@ -0,0 +1,32 @@ +# numpy_visitor.py +from .base_visitor import BaseLibraryVisitor + +class NumpyCallVisitor(BaseLibraryVisitor): + def __init__(self): + super().__init__("numpy") + + def visit_ListComp(self, node): + self.visit(node.elt) + for generator in node.generators: + self.visit(generator) + + def visit_SetComp(self, node): + self.visit(node.elt) + for generator in node.generators: + self.visit(generator) + + def visit_DictComp(self, node): + self.visit(node.key) + self.visit(node.value) + for generator in node.generators: + self.visit(generator) + + def visit_Lambda(self, node): + self.visit(node.body) + + def visit_BinOp(self, node): + if self._is_library_variable(node.left) or self._is_library_variable( + node.right + ): + self._add_call("attribute", "numpy.binary_operation", node.lineno) + self.generic_visit(node) \ No newline at end of file diff --git a/floppy/src/floppy/analysis/visitors/scipy_visitor.py b/floppy/src/floppy/analysis/visitors/scipy_visitor.py new file mode 100644 index 0000000..0b03a1f --- /dev/null +++ b/floppy/src/floppy/analysis/visitors/scipy_visitor.py @@ -0,0 +1,6 @@ +# scipy_visitor.py +from .base_visitor import BaseLibraryVisitor + +class ScipyCallVisitor(BaseLibraryVisitor): + def __init__(self): + super().__init__("scipy") \ No newline at end of file diff --git a/floppy/src/floppy/analysis/visitors/sklearn_visitor.py b/floppy/src/floppy/analysis/visitors/sklearn_visitor.py new file mode 100644 index 0000000..a3e52c6 --- /dev/null +++ b/floppy/src/floppy/analysis/visitors/sklearn_visitor.py @@ -0,0 +1,6 @@ +# sklearn_visitor.py +from .base_visitor import BaseLibraryVisitor + +class SklearnCallVisitor(BaseLibraryVisitor): + def __init__(self): + super().__init__("sklearn") \ No newline at end of file diff --git a/floppy/src/floppy/counting/__init__.py b/floppy/src/floppy/counting/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/floppy/src/floppy/counting/counter.py b/floppy/src/floppy/counting/counter.py new file mode 100644 index 0000000..abde520 --- /dev/null +++ b/floppy/src/floppy/counting/counter.py @@ -0,0 +1,348 @@ +from contextlib import ContextDecorator +from typing import Dict, Any +import numpy as np +from .operations import * +import inspect + +class TrackedArray(np.ndarray): + """Array wrapper that tracks floating point operations using the operation registry.""" + + def __new__(cls, input_array, counter): + # Unwrap if the input_array is already a TrackedArray + if isinstance(input_array, TrackedArray): + input_array = input_array.view(np.ndarray) + + # Create the TrackedArray + obj = np.asarray(input_array).view(cls) + obj.counter = counter + return obj + + def __array_finalize__(self, obj): + """Ensure proper initialization of TrackedArray attributes during array creation. + + This method is called by NumPy whenever a new array is created from an existing one, + including through views, slices, or other array operations. It ensures that the FLOP + counter reference is properly inherited by the new array. + + Args: + obj: Optional[ndarray] + The array from which this array was created. None if the array is being + created from scratch rather than derived from an existing array. + + Note: + This method is essential for maintaining the FLOP counting functionality across + all array operations, as it ensures derived arrays maintain their connection + to the original FlopCounter instance. + + The method handles three main cases: + 1. Direct array creation (obj is None) + 2. View creation (obj is TrackedArray) + 3. Result of array operations (obj is TrackedArray) + """ + if obj is None: + return + self.counter = getattr(obj, "counter", None) + + def __array_ufunc__(self, ufunc, method, *inputs, **kwargs): + """ + Intercept NumPy ufuncs (like add, multiply, etc.) and count FLOPs. + + Args: + ufunc: The NumPy universal function being called (e.g., np.add, np.multiply) + method: The method of the ufunc being called ('__call__', 'reduce', etc.) + *inputs: The input arrays to the ufunc + **kwargs: Additional keyword arguments, including potentially 'out' + + Notes: + 1) Unwrap inputs into base NumPy arrays + - Converts TrackedArrays to their underlying numpy arrays + - Handles nested TrackedArrays through recursive unwrapping + + 2) Handle 'out' parameter separately + - The 'out' parameter specifies pre-allocated array(s) for results + - Can be either a single array or tuple of arrays for multi-output ufuncs + - Must be unwrapped to base arrays so ufunc can write directly to memory + Example: + tracked_out = TrackedArray(np.zeros(3)) + np.add(a, b, out=tracked_out) # Needs unwrapped array for in-place operation + + 3) Perform the actual ufunc operation + + 4) Count FLOPs if active + """ + + # 1) Unwrap inputs into base NumPy arrays + clean_inputs = [] + for inp in inputs: + while isinstance(inp, TrackedArray): + inp = inp.view(np.ndarray) + clean_inputs.append(inp) + + # 2) Handle 'out' parameter separately + if "out" in kwargs: + out = kwargs["out"] + if isinstance(out, tuple): + # Create a new tuple with unwrapped elements + clean_out = tuple( + o.view(np.ndarray) if isinstance(o, TrackedArray) else o + for o in out + ) + kwargs["out"] = clean_out + elif isinstance(out, TrackedArray): + # Unwrap single 'out' parameter if it's a TrackedArray + kwargs["out"] = out.view(np.ndarray) + + # 3) Perform the actual ufunc operation + result = getattr(ufunc, method)(*clean_inputs, **kwargs) + + # 4) Count FLOPs if active + if self.counter: + if not self.counter.should_skip_counting(): + op_name = ufunc.__name__ + if op_name in self.counter.ufunc_operations: + flops = self.counter.ufunc_operations[op_name].count_flops( + *clean_inputs, result=result + ) + self.counter.add_flops(flops) + + # 5) Wrap the result back into a TrackedArray, if applicable + if "out" in kwargs: + # If 'out' was provided, ensure it is properly wrapped + out = kwargs["out"] + if isinstance(out, tuple): + # Create a new tuple with wrapped elements + wrapped_out = tuple( + TrackedArray(o, self.counter) + if isinstance(o, np.ndarray) and not isinstance(o, TrackedArray) + else o + for o in out + ) + if len(wrapped_out) == 1: + return wrapped_out[0] + return wrapped_out # Return the wrapped output tuple + elif isinstance(out, np.ndarray) and not isinstance(out, TrackedArray): + return TrackedArray(out, self.counter) + + # If the result is a scalar or already wrapped, return as is + if isinstance(result, np.ndarray) and not isinstance(result, TrackedArray): + return TrackedArray(result, self.counter) + + return result + + def __getitem__(self, key): + result = super().__getitem__(key) + return ( + type(self)(result, self.counter) + if isinstance(result, np.ndarray) + else result + ) + + def __repr__(self): + return f"TrackedArray(array={super().__repr__()}, counter={id(self.counter)})" + + +class FlopCounter(ContextDecorator): + """ + Context manager that: + 1) monkey-patches np.array => returns TrackedArray + 2) optionally monkey-patches a few high-level calls (np.sum, np.matmul, etc.) + 3) accumulates FLOPs for each operation + """ + + def __init__(self, logger=None): + self.flops = 0 + self._is_active = False + self.logger = logger # Store the logger instance + self.detailed_logging = ( + logger is not None + ) # Enable detailed logging if logger is provided + + self._original_array_func = None + self._original_funcs = {} + + self.ufunc_operations = { + "add": Addition(), + "subtract": Subtraction(), + "multiply": Multiplication(), + "divide": Division(), + "power": PowerOperation(), + "floor_divide": FloorDivideOperation(), + "mod": ModuloOperation(), + "bitwise_and": BitwiseAndOperation(), + "bitwise_or": BitwiseOrOperation(), + "sin": SineOperation(), + "cos": CosineOperation(), + "tan": TangentOperation(), + "arctan": ArcTangentOperation(), + "arcsin": ArcSineOperation(), + "arccos": ArccosOperation(), + "cross": CrossOperation(), + "clip": ClipOperation(), + "where": WhereOperation(), + "min": MinOperation(), + "max": MaxOperation(), + "round": RoundOperation(), + "isnan": IsnanOperation(), + "log": LogOperation(), + } + + self.function_operations = { + "matmul": MatmulOperation(), + "sum": SumOperation(), + "dot": MatmulOperation(), + "linalg.norm": NormOperation(), + "linalg.cond": CondOperation(), + "linalg.inv": InvOperation(), + "linalg.eig": EigOperation(), + "mean": MeanOperation(), + "std": StdOperation(), + "var": VarOperation(), + "average": AverageOperation(), + "trace": TraceOperation(), + "argmin": ArgminOperation(), + "argmax": ArgmaxOperation(), + } + self.patch_targets = { + "matmul": (np, "matmul"), + "sum": (np, "sum"), + "dot": (np, "dot"), + # Functions in np.linalg + "linalg.norm": (np.linalg, "norm"), + "linalg.cond": (np.linalg, "cond"), + "linalg.inv": (np.linalg, "inv"), + "linalg.eig": (np.linalg, "eig"), + # Statistics / reductions in np + "mean": (np, "mean"), + "std": (np, "std"), + "var": (np, "var"), + "average": (np, "average"), + "trace": (np, "trace"), + "argmin": (np, "argmin"), + "argmax": (np, "argmax"), + } + + def _tracked_array(self, *args, **kwargs): + """Create a tracked array from numpy array creation.""" + arr = self._original_array_func(*args, **kwargs) + return TrackedArray(arr, self) + + def _make_wrapper(self, func_name, func): + """ + Create a closure that intercepts the high-level call, + counts FLOPs, then calls the original. + """ + + def wrapper(*args, **kwargs): + # Preprocess arguments to ensure they are valid for `func` + clean_args = [] + for arg in args: + if isinstance(arg, TrackedArray): + # Unwrap nested TrackedArray to its base array + while isinstance(arg, TrackedArray): + arg = arg.view(np.ndarray) + clean_args.append(arg) + + # Clean kwargs similarly + clean_kwargs = {} + for k, v in kwargs.items(): + if isinstance(v, TrackedArray): + # Unwrap TrackedArray in kwargs + clean_kwargs[k] = v.view(np.ndarray) + else: + clean_kwargs[k] = v + + # Call the original function with cleaned arguments + result = func(*clean_args, **clean_kwargs) + + # If recognized, count FLOPs via self._function_operations + if func_name in self.function_operations and self._is_active: + flops = self.function_operations[func_name].count_flops( + *clean_args, result=result + ) + if flops is not None: + self.add_flops(flops) + + return result + + return wrapper + + def __enter__(self): + # Store original numpy array class and array function + self._original_array = np.ndarray + self._original_array_func = np.array + + # Override numpy array creation to return tracked arrays + np.array = self._tracked_array + + # Monkey-patch the functions in _patch_targets + for name, (mod, attr) in self.patch_targets.items(): + original_func = getattr(mod, attr) + self._original_funcs[name] = original_func + wrapped_func = self._make_wrapper(name, original_func) + setattr(mod, attr, wrapped_func) + + # Enable the flop counter after patching is complete + self._is_active = True + return self + + def __exit__(self, *exc): + """ + Deactivate the FLOP counter, restore original functionality. + """ + self._is_active = False + + # Restore original array function + np.array = self._original_array_func + + # Restore original monkey-patched functions + for name, original_func in self._original_funcs.items(): + mod, attr = self.patch_targets[name] + setattr(mod, attr, original_func) + + return False + + @classmethod + def should_skip_counting(cls) -> bool: + """ + Determine if FLOP counting should be skipped based on the call stack. + + We skip counting FLOPs that occur inside library code (like NumPy internals) because: + 1. These operations are already accounted for separately through our higher-level + operation counters (e.g., MatmulOperation, SumOperation, etc.) + 2. Counting both the high-level operation and its internal implementation would + result in double-counting + 3. The internal implementation details of library functions may vary across + versions and platforms, making internal FLOP counts unreliable + + Returns: + bool: True if counting should be skipped (inside library code), False otherwise + """ + # Check for library calls + stack_frames = inspect.stack() + for frame in stack_frames: + if any( + lib in frame.filename + for lib in ("site-packages", "numpy", "scipy", "habitat_sim") + ): + return True + return False + + def add_flops(self, count: int): + """Add to the FLOP count only if counter is active and not in library code.""" + if not self.should_skip_counting(): + if self.detailed_logging and self.logger: + caller_frame = inspect.currentframe().f_back + while caller_frame: + filename = caller_frame.f_code.co_filename + # Skip internal frames from our FLOP counting infrastructure + if not any( + x in filename for x in ["counter.py", "monty_flop_tracer.py"] + ): + line_no = caller_frame.f_lineno + function_name = caller_frame.f_code.co_name + self.logger.debug( + f"FLOPs: {count} | File: {filename} | Line: {line_no} | Function: {function_name}" + ) + break + caller_frame = caller_frame.f_back + self.flops += count diff --git a/floppy/src/floppy/counting/operations/__init__.py b/floppy/src/floppy/counting/operations/__init__.py new file mode 100644 index 0000000..ff7dbc6 --- /dev/null +++ b/floppy/src/floppy/counting/operations/__init__.py @@ -0,0 +1,8 @@ +from .arithmetic import * +from .bitwise import * +from .exponential import * +from .linalg import * +from .reduction import * +from .special import * +from .statistical import * +from .trigonometry import * diff --git a/floppy/src/floppy/counting/operations/arithmetic.py b/floppy/src/floppy/counting/operations/arithmetic.py new file mode 100644 index 0000000..28cbb26 --- /dev/null +++ b/floppy/src/floppy/counting/operations/arithmetic.py @@ -0,0 +1,108 @@ +import numpy as np +from typing import Any + +__all__ = [ + "Addition", + "Subtraction", + "Multiplication", + "Division", + "FloorDivideOperation", + "ModuloOperation", +] + +class ArithmeticOperation: + """Base class for arithmetic operations.""" + + def __init__(self, name: str): + self.name = name + + def count_flops(self, *args: Any, result: Any) -> int: + """Counts the floating point operations (FLOPs) for an arithmetic operation. + + Handles both scalar and array operations. For scalar operations, counts one FLOP + per element in the non-scalar array. For array operations, counts one FLOP per + element in the result array, taking into account broadcasting. + + Args: + *args: Variable length argument list containing the input operands. + Expected to have at least 2 arguments where each can be a scalar + or numpy array. + result: The result of the arithmetic operation, used to determine the + final shape after broadcasting. + + Returns: + int: The total number of FLOPs performed in the operation, calculated as: + - For scalar operations: size of the non-scalar array + - For array operations: product of the result array's dimensions + """ + # Handle scalar operations + if np.isscalar(args[0]) or np.isscalar(args[1]): + array_arg = args[1] if np.isscalar(args[0]) else args[0] + return np.size(array_arg) + + # Get the result shape directly from the actual result + # This ensures we correctly account for broadcasting + return np.size(np.asarray(result)) + + +class Addition(ArithmeticOperation): + """Class for addition operation.""" + + def __init__(self): + super().__init__("add") + + +class Subtraction(ArithmeticOperation): + """Class for subtraction operation.""" + + def __init__(self): + super().__init__("subtract") + + +class Multiplication(ArithmeticOperation): + """Class for multiplication operation.""" + + def __init__(self): + super().__init__("multiply") + + +class Division(ArithmeticOperation): + """Class for division operation. + + Note: + While division operations can require multiple FLOPs in hardware (e.g., 4 FLOPs), + we follow the common convention of counting it as 1 FLOP for simplicity. + This aligns with standard practice in numerical analysis + (see https://www.stat.cmu.edu/~ryantibs/convexopt-F18/scribes/Lecture_19.pdf). + """ + + def __init__(self): + super().__init__("divide") + +class FloorDivideOperation: + """FLOP count for floor divide operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for floor divide operation. + + Each element requires: + - 1 division operation + - 1 floor/truncation operation + Total: 2 FLOPs per element + """ + return 2 * np.size(args[0]) + + +class ModuloOperation: + """FLOP count for modulo operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for modulo operation. + + Each element requires: + - 1 division (quotient = a ÷ b) + - 1 multiplication (product = quotient * b) + - 1 subtraction (remainder = a - product) + Total: 3 FLOPs per element + """ + return 3 * np.size(args[0]) \ No newline at end of file diff --git a/floppy/src/floppy/counting/operations/bitwise.py b/floppy/src/floppy/counting/operations/bitwise.py new file mode 100644 index 0000000..386ae25 --- /dev/null +++ b/floppy/src/floppy/counting/operations/bitwise.py @@ -0,0 +1,29 @@ +import numpy as np +from typing import Any + +__all__ = [ + "BitwiseAndOperation", + "BitwiseOrOperation", +] + + +class BitwiseAndOperation: + """FLOP count for bitwise and operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for bitwise and operation. + + Each element requires 1 bitwise and operation. + """ + return np.size(args[0]) + + +class BitwiseOrOperation: + """FLOP count for bitwise or operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for bitwise or operation. + + Each element requires 1 bitwise or operation. + """ + return np.size(args[0]) diff --git a/floppy/src/floppy/counting/operations/exponential.py b/floppy/src/floppy/counting/operations/exponential.py new file mode 100644 index 0000000..8d0ba90 --- /dev/null +++ b/floppy/src/floppy/counting/operations/exponential.py @@ -0,0 +1,55 @@ +import numpy as np +from typing import Any + +__all__ = [ + "LogOperation", + "PowerOperation", +] + + +class LogOperation: + """FLOP count for logarithm operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for logarithm operation. + + Each logarithm typically requires ~20-30 FLOPs depending on the implementation + and desired precision. Common implementations use series expansions or + iterative methods that involve multiple multiplications and divisions. + We use a conservative estimate of 20 FLOPs per logarithm. + """ + return 20 * np.size(args[0]) + + +class PowerOperation: + """FLOP count for power operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for power operation. + + FLOP count depends on the exponent: + - For integer exponents > 0: Uses repeated multiplication, requiring (exponent-1) FLOPs + - For integer exponent = 0: No FLOPs (just returns 1) + - For integer exponent < 0: Same as positive + 1 division + - For fractional exponents: Uses logarithm (~20 FLOPs) and exponential (~20 FLOPs), or total ~40 FLOPs + + Args: + args: (base, exponent) + result: Result of the operation + """ + base, exponent = args + n = np.size(base) + + if np.isscalar(exponent): + if float(exponent).is_integer(): + exp = abs(int(exponent)) + flops_per_element = max(0, exp - 1) # exp-1 multiplications needed + if exponent < 0: + flops_per_element += 1 # Additional division for negative exponents + else: + flops_per_element = 40 # Approximate FLOPs for fractional exponents + else: + # If exponent is an array, use worst case (fractional exponent) + flops_per_element = 40 + + return n * flops_per_element diff --git a/floppy/src/floppy/counting/operations/linalg.py b/floppy/src/floppy/counting/operations/linalg.py new file mode 100644 index 0000000..8cc4bf1 --- /dev/null +++ b/floppy/src/floppy/counting/operations/linalg.py @@ -0,0 +1,304 @@ +import numpy as np +from typing import Any, Optional, Tuple, Union + +__all__ = [ + "MatmulOperation", + "TraceOperation", + "NormOperation", + "CondOperation", + "InvOperation", + "EigOperation", +] + + +class MatmulOperation: + """FLOP counter for matrix multiplication operations.""" + + def _compute_broadcast_batch_shape( + self, shape1: Tuple[int, ...], shape2: Tuple[int, ...] + ) -> Tuple[int, ...]: + """ + Compute the broadcasted shape of batch dimensions. + + Args: + shape1: Shape of first array + shape2: Shape of second array + + Returns: + Tuple[int, ...]: Broadcasted batch shape + """ + batch1 = shape1[:-2] if len(shape1) > 2 else () + batch2 = shape2[:-2] if len(shape2) > 2 else () + + if not batch1 and not batch2: + return () + + return np.broadcast_shapes(batch1, batch2) + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """ + Count FLOPs for matrix multiplication with broadcasting support. + + For matrix multiplication C = A @ B: + - Each element in the result requires one multiplication and one addition per + inner dimension element + - Total FLOPs = 2 * M * N * P * batch_size + where: + M = rows in result + N = inner dimension (columns of A, rows of B) + P = columns in result + batch_size = product of broadcasted batch dimensions + + Args: + *args: Input arrays + result: Result of the operation + + Returns: + Optional[int]: Number of FLOPs or None if invalid + """ + try: + a, b = np.asarray(args[0]), np.asarray(args[1]) + + # Handle 1D vector cases + if a.ndim == 1 and b.ndim == 1: + # Vector dot product: 2N-1 FLOPs (N multiplications, N-1 additions) + return 2 * a.shape[0] - 1 + + if a.ndim == 1: # 1D × 2D + M, N = 1, a.shape[0] + P = b.shape[1] + elif b.ndim == 1: # 2D × 1D + M, N = a.shape + P = 1 + else: # ND × ND + # Use negative indexing to handle arbitrary batch dimensions + # shape = (*batch_dims, M, N) for first array + # shape = (*batch_dims, N, P) for second array + M = a.shape[-2] + N = a.shape[-1] # same as b.shape[-2] + P = b.shape[-1] + + # Compute broadcasted batch shape + batch_shape = self._compute_broadcast_batch_shape(a.shape, b.shape) + batch_size = np.prod(batch_shape) if batch_shape else 1 + + # Each element requires N multiplications and N-1 additions + # For each M×P elements in the result + return batch_size * M * P * (2 * N - 1) + + except Exception as e: + raise ValueError(f"Error counting matmul FLOPs: {str(e)}") + + +class TraceOperation: + """FLOP count for trace operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for trace operation. + + Trace is the sum of diagonal elements, requiring (n-1) additions + where n is the number of diagonal elements. + """ + n = min(args[0].shape) # Get the minimum dimension (for non-square matrices) + return n - 1 + + +class NormOperation: + """FLOP count for np.linalg.norm operation with different norms. + + This class implements FLOP counting for both vector and matrix norms. + For vectors, it supports p-norms including L1, L2, and L∞. + For matrices, it supports common matrix norms including Frobenius, + spectral (2-norm), nuclear, and induced norms (L1 and L∞). + """ + + def count_flops( + self, + *args: Any, + ord: Optional[Union[int, float, str]] = None, + axis: Optional[Union[int, tuple]] = None, + keepdims: bool = False, + result: Any = None, + ) -> int: + """Count FLOPs for norm calculation. + + Args: + args: Variable length argument list. First argument is the input array. + ord: Order of the norm. + axis: If axis is an integer, it specifies the axis of x along which to compute the vector norms. + If axis is a 2-tuple, it specifies the axes that hold 2-D matrices for matrix norm computation. + If axis is None, either a vector norm (when x is 1-D) or a matrix norm (when x is 2-D) is returned. + keepdims: If this is set to True, the axes which are normed over are left in the result as dimensions with size one. + result: Not used, kept for API consistency. + + Returns: + Number of floating point operations. + + Note: + Vector norm FLOP counts: + - L2 norm: 2n FLOPs (n multiplies, n-1 adds, 10 sqrt) + - L1 norm: 2n-1 FLOPs (n absolute values, n-1 additions) + - L∞ norm: 2n-1 FLOPs (n absolute values, n-1 comparisons) + - General p-norm: uses PowerOperation for p-th powers + * n absolute values + * n power operations (via PowerOperation) + * (n-1) additions + * 1 final power operation + + Matrix norm FLOP counts: + - Frobenius: mn*2 FLOPs (mn multiplies, mn-1 adds, 1 sqrt) + - L1 (max col sum): mn+m-1 FLOPs (mn abs, m(n-1) adds, m-1 comparisons) + - L∞ (max row sum): mn+n-1 FLOPs (mn abs, n(m-1) adds, n-1 comparisons) + - L2 (spectral): ~14n³ FLOPs (SVD based on Trefethen and Bau) + - Nuclear: ~14n³ + n FLOPs (SVD + sum of singular values) + """ + x = args[0] + + if axis is None: + # If no axis specified, compute norm over entire array + if x.ndim <= 1: + return self._count_vector_norm_flops(x, ord) + elif x.ndim == 2: + return self._count_matrix_norm_flops(x, ord) + else: + # For higher dimensions, treat as vector norm over flattened array + return self._count_vector_norm_flops(x.reshape(-1), ord) + + elif isinstance(axis, tuple) and len(axis) == 2: + # Matrix norm along specified axes + # Count FLOPs for each matrix in the remaining dimensions + matrices_count = np.prod( + [x.shape[i] for i in range(x.ndim) if i not in axis] + ) + single_matrix_flops = self._count_matrix_norm_flops( + x.transpose((*axis, *[i for i in range(x.ndim) if i not in axis]))[ + 0, 0 + ], + ord, + ) + return matrices_count * single_matrix_flops + + elif isinstance(axis, (int, tuple)): + # Vector norm along specified axis/axes + # Count FLOPs for each vector + vectors_count = np.prod( + [ + x.shape[i] + for i in range(x.ndim) + if i not in (axis if isinstance(axis, tuple) else (axis,)) + ] + ) + vector_size = np.prod( + [x.shape[i] for i in (axis if isinstance(axis, tuple) else (axis,))] + ) + return vectors_count * self._count_vector_norm_flops( + np.ones(vector_size), ord + ) + + else: + raise ValueError(f"Invalid axis parameter: {axis}") + + def _count_vector_norm_flops( + self, x: np.ndarray, ord: Optional[Union[int, float, str]] + ) -> int: + """Count FLOPs for vector norm calculation.""" + n = np.size(x) + + if ord is None or ord == 2: + return 2 * n + 10 # n multiplies, n-1 adds, 10 sqrt + elif ord == 1: + return 2 * n - 1 # n absolute values, n-1 additions + elif ord in (np.inf, float("inf"), -np.inf, float("-inf")): + return 2 * n - 1 # n absolute values, n-1 comparisons + else: + # For general p-norm, assume worst case ~40 FLOPs for power operation (see PowerOperation) + # 1. n absolute values + # 2. n power operations + # 3. (n-1) additions + # 4. 1 final power (1/p) + + power_flops = n + 40 * n + (n - 1) + 40 + return power_flops + + def _count_matrix_norm_flops( + self, x: np.ndarray, ord: Optional[Union[int, float, str]] + ) -> int: + """Count FLOPs for matrix norm calculation.""" + m, n = x.shape + + if ord is None or ord == "fro": + return m * n * 2 # mn multiplies, mn-1 adds, 1 sqrt + elif ord == 1: + return m * n + m - 1 # mn abs, m(n-1) adds, m-1 comparisons + elif ord in (np.inf, float("inf")): + return m * n + n - 1 # mn abs, n(m-1) adds, n-1 comparisons + elif ord == 2: + # Spectral norm (largest singular value) + # Using estimate from Trefethen and Bau (see CondOperation) + k = min(m, n) + return 14 * k**3 # SVD complexity + elif ord == "nuc": + # Nuclear norm (sum of singular values) + # SVD + sum of singular values + k = min(m, n) + return 14 * k**3 + k # SVD + k-1 additions + else: + raise ValueError( + f"FLOP count for norm order '{ord}' for matrix norm not implemented" + ) + + +class CondOperation: + """FLOP count for np.linalg.cond operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for condition number calculation. + + For a square matrix (m=n), the total FLOP count is: + - SVD decomposition (~14n^3) + An estimate for complexity of SVD is ~2mn^2 + 11n^3 per equation 11.22 + in "Numerical Linear Algebra" by Trefethen and Bau. + + - Division of largest by smallest singular value (1) + + Total: ~14n^3 + 1 FLOPs + """ + n = args[0].shape[0] + return 14 * n**3 + 1 + + +class InvOperation: + """FLOP count for np.linalg.inv operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for matrix inversion. + + Matrix inversion using LU decomposition: + - LU decomposition (~2/3 n³) + - Forward and backward substitution (~2n²) + An estimate for complexity of LU decomposition is ~2/3 n³ FLOPs per equation 20.8 + in "Numerical Linear Algebra" by Trefethen and Bau. + Total: ~2/3 n³ + 2n² FLOPs + """ + n = args[0].shape[0] + return (2 * n**3) // 3 + 2 * n**2 + + +class EigOperation: + """FLOP count for np.linalg.eig operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for eigenvalue decomposition. + + Eigenvalue decomposition using QR algorithm: + - Reduction to Hessenberg form (~10/3 n³) + An estimate for complexity of reduction to Hessenberg form is ~10/3 n³ FLOPs per equation 26.1 + in "Numerical Linear Algebra" by Trefethen and Bau. + - QR iterations using Householder reflections: ~4/3 n³ FLOPs per iteration (~20 iterations) + An estimate for complexity of QR iterations is ~4/3 n³ FLOPs per equation 10.9 + in "Numerical Linear Algebra" by Trefethen and Bau. + + Total: 10/3 n³ + 4/3 n³ * 20 = 10/3 n³ + 80/3 n³ = 90/3 n³ = 30 n³ FLOPs + """ + n = args[0].shape[0] + return 30 * n**3 diff --git a/floppy/src/floppy/counting/operations/reduction.py b/floppy/src/floppy/counting/operations/reduction.py new file mode 100644 index 0000000..4c7c54c --- /dev/null +++ b/floppy/src/floppy/counting/operations/reduction.py @@ -0,0 +1,79 @@ +import numpy as np +from typing import Any + +__all__ = [ + "SumOperation", + "MinOperation", + "MaxOperation", + "ArgminOperation", + "ArgmaxOperation", +] + + +class SumOperation: + """FLOP count for sum operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for sum operation. + + This implementation provides an upper bound by counting (n-1) additions + where n is the total size of the array. We ignore the specific axis of + reduction since the actual FLOP count would be less than or equal to + this upper bound when summing along specific axes. + + Args: + *args: Input arrays (first argument is the array to sum) + result: Result of the operation + + Returns: + int: Number of floating point operations (additions) + """ + return np.size(args[0]) - 1 + + +class MinOperation: + """FLOP count for min operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for min operation. + + Finding the minimum requires comparing each pair of elements sequentially. + For n elements, we need (n-1) comparisons total. + """ + return np.size(args[0]) - 1 + + +class MaxOperation: + """FLOP count for max operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for max operation. + + Finding the maximum requires comparing each pair of elements sequentially. + For n elements, we need (n-1) comparisons total. + """ + return np.size(args[0]) - 1 + + +class ArgminOperation: + """FLOP count for argmin operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for argmin operation. + + Finding the minimum index requires comparing each element with the current minimum, + similar to min operation. + """ + return np.size(args[0]) - 1 + + +class ArgmaxOperation: + """FLOP count for argmax operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for argmax operation. + + Finding the maximum index requires comparing each element with the current maximum, + similar to max operation. + """ + return np.size(args[0]) - 1 diff --git a/floppy/src/floppy/counting/operations/special.py b/floppy/src/floppy/counting/operations/special.py new file mode 100644 index 0000000..2e9d4f7 --- /dev/null +++ b/floppy/src/floppy/counting/operations/special.py @@ -0,0 +1,53 @@ +import numpy as np +from typing import Any + +__all__ = [ + "ClipOperation", + "WhereOperation", + "RoundOperation", + "IsnanOperation", +] + + +class ClipOperation: + """FLOP count for clip operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for clipping. + + Each element requires 2 comparisons (for min and max bounds). + """ + return 2 * np.size(args[0]) + + +class WhereOperation: + """FLOP count for where operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for where operation. + + Each element requires 1 comparison operation. + """ + return np.size(args[0]) + + +class RoundOperation: + """FLOP count for round operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for round operation. + + Each element requires 1 comparison operation. + """ + return np.size(args[0]) + + +class IsnanOperation: + """FLOP count for isnan operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for isnan operation. + + Each element requires 1 comparison operation. + """ + return np.size(args[0]) diff --git a/floppy/src/floppy/counting/operations/statistical.py b/floppy/src/floppy/counting/operations/statistical.py new file mode 100644 index 0000000..b12a61e --- /dev/null +++ b/floppy/src/floppy/counting/operations/statistical.py @@ -0,0 +1,100 @@ +import numpy as np +from typing import Any + +__all__ = [ + "MeanOperation", + "StdOperation", + "VarOperation", + "AverageOperation", +] + + +class MeanOperation: + """FLOP count for mean operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for mean operation. + + Mean requires: + - (n-1) additions to sum all elements + - 1 division for the final average + """ + return np.size(args[0]) # (n-1) additions + 1 division + + +class StdOperation: + """FLOP count for standard deviation operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for standard deviation operation. + + Standard deviation requires: + - n FLOPs for mean calculation + - n subtractions from mean + - n multiplications for squaring + - (n-1) additions for sum + - 1 division for mean of squares + - 1 square root + Total: 4n + 1 FLOPs + """ + n = np.size(args[0]) + return 4 * n + 1 + + +class VarOperation: + """FLOP count for variance operation.""" + + def count_flops(self, *args: Any, result: Any) -> int: + """Count FLOPs for variance operation. + + Variance requires: + - n FLOPs for mean calculation + - n subtractions from mean + - n multiplications for squaring + - (n-1) additions for sum + - 1 division for final result + Total: 4n FLOPs + """ + n = np.size(args[0]) + return 4 * n + + +class AverageOperation: + """FLOP count for average operation.""" + + def count_flops(self, *args: Any, result: Any, **kwargs: Any) -> int: + """Count FLOPs for average operation. + + Unweighted average: + - n additions for sum + - 1 division + Total: n + 1 FLOPs + + Weighted average: + - n multiplications for weights + - n additions for weighted sum + - 1 division by sum of weights + Total: 2n + 1 FLOPs + + Args: + *args: Input arrays + result: Result of the operation + **kwargs: Additional keyword arguments (e.g., weights) + + Returns: + int: Total FLOPs + """ + if not args: + return 0 + + array = args[0] # Input array + weights = kwargs.get("weights", None) + + n = np.size(array) # Total number of elements in the input array + + if weights is not None: + # Weighted average: weighted sum + sum of weights + division + return 2 * n + 1 # 2n operations for weighted sum and 1 division + else: + # Unweighted average: sum + division + return n + 1 # n operations for sum and 1 division diff --git a/floppy/src/floppy/counting/operations/trigonometry.py b/floppy/src/floppy/counting/operations/trigonometry.py new file mode 100644 index 0000000..15341b7 --- /dev/null +++ b/floppy/src/floppy/counting/operations/trigonometry.py @@ -0,0 +1,153 @@ +import numpy as np +from typing import Any, Optional + +__all__ = [ + "SineOperation", + "CosineOperation", + "CrossOperation", + "ArccosOperation", + "TangentOperation", + "ArcTangentOperation", + "ArcSineOperation", +] + +class SineOperation: + """FLOP counter for sine operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for sine operation. + + Sine is typically implemented using Taylor series: + sin(x) = x - x³/3! + x⁵/5! - x⁷/7! + ... + + Each term requires: + - Power calculation (2-3 FLOPs) + - Factorial division (1 FLOP) + - Addition to sum (1 FLOP) + + With ~7-8 terms for good precision, plus argument reduction, + we estimate 20 FLOPs per value. This was also chosen to be consistent + with the log operation, which also uses some form of series expansion. + """ + return 20 * np.size(result) + + +class CosineOperation: + """FLOP counter for cosine operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for cosine operation. + + Cosine is typically implemented using Taylor series: + cos(x) = 1 - x²/2! + x⁴/4! - x⁶/6! + ... + + Each term requires: + - Power calculation (2-3 FLOPs) + - Factorial division (1 FLOP) + - Addition to sum (1 FLOP) + + With ~7-8 terms for good precision, plus argument reduction, + we estimate 20 FLOPs per value for consistency with sine and log operations. + """ + return 20 * np.size(result) + +class CrossOperation: + """FLOP counter for vector cross product operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for cross product operation. + + Note: Cross product is only defined for 3D vectors (and 7D, though rarely used). + For 3D vectors, cross product requires: + - 6 multiplications + - 3 subtractions + Total: 9 FLOPs per cross product + """ + # Get number of cross products being computed + num_operations = max( + 1, result.shape[0] if isinstance(result, np.ndarray) else 1 + ) + return 9 * num_operations + +class ArccosOperation: + """FLOP counter for inverse cosine operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for inverse cosine operation. + + Arccos can be computed using arctan: + arccos(x) = 2 * arctan(sqrt(1-x)/sqrt(1+x)) + + This requires: + - Two subtractions (1-x, 1+x): 2 FLOPs + - Two square roots: 20 FLOPs (10 each, using Newton iteration) + - One division: 1 FLOP + - One arctan: 20 FLOPs + - One multiplication by 2: 1 FLOP + + Total per element: 44 FLOPs + """ + # Handle both scalar and array inputs + input_value = args[0] + num_elements = 1 if np.isscalar(input_value) else np.size(input_value) + return 44 * num_elements + + +class TangentOperation: + """FLOP counter for tangent operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for tangent operation. + + Tangent can be computed using Taylor series: + tan(x) = x + x³/3 + 2x⁵/15 + 17x⁷/315 + ... + + Each term requires: + - Power calculation (2-3 FLOPs) + - Coefficient multiplication/division (1-2 FLOPs) + - Addition to sum (1 FLOP) + + With ~7-8 terms for good precision, plus argument reduction, + we estimate 20 FLOPs per value for consistency with other trig operations. + """ + return 20 * np.size(result) + + +class ArcTangentOperation: + """FLOP counter for inverse tangent operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for inverse tangent operation. + + Using Taylor series: arctan(x) = x - x³/3 + x⁵/5 - x⁷/7 + ... + + Each term requires: + - Power calculation (2-3 FLOPs) + - Division by odd number (1 FLOP) + - Addition to sum (1 FLOP) + + With ~7-8 terms for good precision, plus argument reduction, + we estimate 20 FLOPs per value for consistency with sine operation. + """ + return 20 * np.size(result) + + +class ArcSineOperation: + """FLOP counter for inverse sine operations.""" + + def count_flops(self, *args: Any, result: Any) -> Optional[int]: + """Count FLOPs for inverse sine operation. + + Arcsine can be computed using arctan: + arcsin(x) = arctan(x/sqrt(1-x²)) + + This requires: + - One multiplication (x²): 1 FLOP + - One subtraction (1-x²): 1 FLOP + - One square root: 10 FLOPs (using Newton iteration) + - One division: 1 FLOP + - One arctan: 20 FLOPs + + Total per element: 33 FLOPs + """ + return 33 * np.size(result) diff --git a/floppy/src/floppy/counting/tracer.py b/floppy/src/floppy/counting/tracer.py new file mode 100644 index 0000000..eb2a5e9 --- /dev/null +++ b/floppy/src/floppy/counting/tracer.py @@ -0,0 +1,329 @@ +from src.floppy.counting.counter import FlopCounter +import csv +from pathlib import Path +import time +from typing import Optional, Callable +from dataclasses import dataclass +from contextlib import contextmanager +import inspect +import logging + + +@dataclass +class MethodTrace: + """Dataclass for storing method trace information.""" + + timestamp: float + episode: int + method_name: str + flops: int + parent_method: Optional[str] = None + + +class MontyFlopTracer: + """Tracks FLOPs for Monty class methods.""" + + def __init__( + self, + experiment_name, + monty_instance, + experiment_instance, + train_dataloader_instance, + eval_dataloader_instance, + motor_system_instance, + log_path=None, + detailed_logging=True, + ): + self.experiment_name = experiment_name + self.monty = monty_instance + self.experiment = experiment_instance + self.train_dataloader = train_dataloader_instance + self.eval_dataloader = eval_dataloader_instance + self.motor_system = motor_system_instance + self.detailed_logging = detailed_logging + + # Setup logging first + timestamp = time.strftime("%Y%m%d_%H%M%S") + self.log_path = ( + Path( + log_path + or f"~/tbp/monty_lab/floppy/results/counting/flop_traces_{self.experiment_name}_{timestamp}.csv" + ) + .expanduser() + .resolve() + ) + if not self.log_path.parent.exists(): + self.log_path.parent.mkdir(parents=True, exist_ok=True) + + if detailed_logging: + # Create a logger with a unique name + self.logger = logging.getLogger(f"flop_tracer_{timestamp}") + self.logger.setLevel(logging.DEBUG) + + # Create handlers + file_handler = logging.FileHandler( + self.log_path.parent / "detailed_flops.log" + ) + console_handler = logging.StreamHandler() + + # Create formatter + formatter = logging.Formatter("%(asctime)s | %(message)s") + file_handler.setFormatter(formatter) + console_handler.setFormatter(formatter) + + # Add handlers to logger + self.logger.addHandler(file_handler) + self.logger.addHandler(console_handler) + + # Initialize FlopCounter with the logger + self.flop_counter = FlopCounter( + logger=self.logger if detailed_logging else None + ) + + self.total_flops = 0 + self.current_episode = 0 + self._method_stack = [] + self._active_counter = False + self._current_flops_stack = [] + self._call_stack = [] # Track actual call stack, not just wrapped methods + + self._initialize_csv() + self._original_monty_methods = self._collect_monty_methods() + self._original_experiment_methods = self._collect_experiment_methods() + if self.train_dataloader is not None: + self._original_train_dataloader_methods = ( + self._collect_train_dataloader_methods() + ) + if self.eval_dataloader is not None: + self._original_eval_dataloader_methods = ( + self._collect_eval_dataloader_methods() + ) + if self.motor_system is not None: + self._original_motor_system_methods = self._collect_motor_system_methods() + self._wrap_methods() + + def _initialize_csv(self): + """Initialize CSV file with headers.""" + # Create parent directories if they don't exist + self.log_path.parent.mkdir(parents=True, exist_ok=True) + + # Write headers + with open(self.log_path, "w", newline="") as f: + writer = csv.writer(f) + writer.writerow(["timestamp", "episode", "method", "flops"]) + + def _log_trace(self, trace: MethodTrace): + """Log a method trace to the CSV file.""" + with open(self.log_path, "a", newline="") as f: + writer = csv.writer(f) + writer.writerow( + [ + trace.timestamp, + trace.episode, + trace.method_name, + trace.flops, + trace.parent_method, + ] + ) + + def _collect_monty_methods(self): + """Collect methods that need to be wrapped.""" + return { + "step": (self.monty.step, "monty.step"), + "_matching_step": (self.monty._matching_step, "monty._matching_step"), + "_exploratory_step": ( + self.monty._exploratory_step, + "monty._exploratory_step", + ), + } + + def _collect_experiment_methods(self): + """Collect methods that need to be wrapped.""" + return { + "run_episode": (self.experiment.run_episode, "experiment.run_episode"), + "pre_epoch": (self.experiment.pre_epoch, "experiment.pre_epoch"), + "pre_episode": (self.experiment.pre_episode, "experiment.pre_episode"), + "pre_step": (self.experiment.pre_step, "experiment.pre_step"), + "post_step": (self.experiment.post_step, "experiment.post_step"), + "post_episode": (self.experiment.post_episode, "experiment.post_episode"), + } + + def _collect_train_dataloader_methods(self): + return { + "pre_episode": ( + self.train_dataloader.pre_episode, + "train_dataloader.pre_episode", + ), + } + + def _collect_eval_dataloader_methods(self): + return { + "pre_episode": ( + self.eval_dataloader.pre_episode, + "eval_dataloader.pre_episode", + ), + "get_good_view_with_patch_refinement": ( + self.eval_dataloader.get_good_view_with_patch_refinement, + "eval_dataloader.get_good_view_with_patch_refinement", + ), + "get_good_view": ( + self.eval_dataloader.get_good_view, + "eval_dataloader.get_good_view", + ), + } + + def _collect_motor_system_methods(self): + return { + "orient_to_object": ( + self.motor_system.orient_to_object, + "motor_system.orient_to_object", + ), + "move_close_enough": ( + self.motor_system.move_close_enough, + "motor_system.move_close_enough", + ), + } + + @contextmanager + def _method_context(self, method_name: str): + """Context manager for tracking method hierarchy.""" + self._method_stack.append(method_name) + try: + yield + finally: + self._method_stack.pop() + + def _create_wrapper( + self, method_name: str, original_method: Callable, full_name: str + ) -> Callable: + """Create a wrapper for the given method.""" + + def wrapped(*args, **kwargs): + is_outer_call = not self._active_counter + + if is_outer_call: + self._active_counter = True + self.flop_counter.flops = 0 + + # Get the actual caller from the call stack + caller_frame = inspect.currentframe().f_back + caller_name = caller_frame.f_code.co_name if caller_frame else None + + start_flops = self.flop_counter.flops + self._current_flops_stack.append(start_flops) + + with self._method_context(full_name): # Use full_name here + # Only use flop_counter context manager for outer calls + if is_outer_call: + with self.flop_counter: + result = original_method(*args, **kwargs) + else: + result = original_method(*args, **kwargs) + + method_flops = self.flop_counter.flops - self._current_flops_stack.pop() + + if is_outer_call: + self._active_counter = False + self.total_flops += self.flop_counter.flops + + trace = MethodTrace( + timestamp=time.time(), + episode=self.current_episode, + method_name=full_name, # Use full_name here + flops=method_flops, + parent_method=caller_name, + ) + self._log_trace(trace) + if self.detailed_logging: + logging.debug(f"Logged trace: {trace}") + + # Increment episode counter after run_episode completes + if method_name == "run_episode": + self.current_episode += 1 + + return result + + return wrapped + + def _wrap_methods(self) -> None: + """Wrap methods to count FLOPs.""" + for method_name, ( + original_method, + full_name, + ) in self._original_monty_methods.items(): + wrapped_method = self._create_wrapper( + method_name, original_method, full_name + ) + setattr(self.monty, method_name, wrapped_method) + + for method_name, ( + original_method, + full_name, + ) in self._original_experiment_methods.items(): + wrapped_method = self._create_wrapper( + method_name, original_method, full_name + ) + setattr(self.experiment, method_name, wrapped_method) + + if self.train_dataloader is not None: + for method_name, ( + original_method, + full_name, + ) in self._original_train_dataloader_methods.items(): + wrapped_method = self._create_wrapper( + method_name, original_method, full_name + ) + setattr(self.train_dataloader, method_name, wrapped_method) + + if self.eval_dataloader is not None: + for method_name, ( + original_method, + full_name, + ) in self._original_eval_dataloader_methods.items(): + wrapped_method = self._create_wrapper( + method_name, original_method, full_name + ) + setattr(self.eval_dataloader, method_name, wrapped_method) + + if self.motor_system is not None: + for method_name, ( + original_method, + full_name, + ) in self._original_motor_system_methods.items(): + wrapped_method = self._create_wrapper( + method_name, original_method, full_name + ) + setattr(self.motor_system, method_name, wrapped_method) + + def unwrap(self): + """Restore original methods.""" + for method_name, original_method in self._original_monty_methods.items(): + setattr(self.monty, method_name, original_method) + for method_name, original_method in self._original_experiment_methods.items(): + setattr(self.experiment, method_name, original_method) + + if self.train_dataloader is not None: + for ( + method_name, + original_method, + ) in self._original_train_dataloader_methods.items(): + setattr(self.train_dataloader, method_name, original_method) + + if self.eval_dataloader is not None: + for ( + method_name, + original_method, + ) in self._original_eval_dataloader_methods.items(): + setattr(self.eval_dataloader, method_name, original_method) + + if self.motor_system is not None: + for ( + method_name, + original_method, + ) in self._original_motor_system_methods.items(): + setattr(self.motor_system, method_name, original_method) + + def reset(self): + """Reset FLOP counters.""" + self.total_flops = 0 + self.flop_counter.flops = 0 diff --git a/floppy/tests/test_add.py b/floppy/tests/test_add.py new file mode 100644 index 0000000..6071d9d --- /dev/null +++ b/floppy/tests/test_add.py @@ -0,0 +1,70 @@ +"""Run using python tests/test_add.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_add_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + result = a + b + assert counter.flops == 3 + np.testing.assert_array_equal(result, np.array([5, 7, 9])) + + +def test_add_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + result = np.add(a, b) + assert counter.flops == 3 + np.testing.assert_array_equal(result, np.array([5, 7, 9])) + + +def test_add_method_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + result = a.add(b) + assert counter.flops == 3 + np.testing.assert_array_equal(result, np.array([5, 7, 9])) + + +def test_add_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a += b + assert counter.flops == 3 + np.testing.assert_array_equal(a, np.array([5, 7, 9])) + + +def test_add_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + result = a + b + assert counter.flops == 3 + np.testing.assert_array_equal(result, np.array([3, 4, 5])) + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + result = b + a + assert counter.flops == 3 + np.testing.assert_array_equal(result, np.array([3, 4, 5])) + + +if __name__ == "__main__": + test_add_operator_syntax() + test_add_ufunc_syntax() + test_add_method_syntax() + test_add_augmented_assignment() + test_add_broadcasting() diff --git a/floppy/tests/test_arccosine.py b/floppy/tests/test_arccosine.py new file mode 100644 index 0000000..fa7309b --- /dev/null +++ b/floppy/tests/test_arccosine.py @@ -0,0 +1,51 @@ +"""Run using python tests/test_arccosine.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_arccos_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([-0.5, 0.0, 0.5]) # values within valid domain [-1, 1] + result = np.arccos(a) + assert counter.flops == 132 # 44 FLOPs * 3 elements = 132 + np.testing.assert_allclose( + result, np.array([2.0943951, 1.57079633, 1.04719755]) + ) + + +def test_arccos_scalar(): + counter = FlopCounter() + with counter: + # FIXME: counter.flops returns 0 + a = 0.5 + result = np.arccos(a) + assert counter.flops == 44 # 44 FLOPs * 1 element = 44 + np.testing.assert_allclose(result, np.array([1.04719755])) + + +def test_arccos_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([[0.1, 0.2], [0.3, 0.4]]) + result = np.arccos(a) + assert counter.flops == 176 # 44 FLOPs * 4 elements = 176 + np.testing.assert_allclose( + result, np.array([[1.47062894, 1.36943841], [1.26610367, 1.15927948]]) + ) + + +def test_arccos_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.arccos(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_arccos_ufunc_syntax() + # test_arccos_scalar() + test_arccos_broadcasting() + test_arccos_empty() diff --git a/floppy/tests/test_arcsine.py b/floppy/tests/test_arcsine.py new file mode 100644 index 0000000..a1db58f --- /dev/null +++ b/floppy/tests/test_arcsine.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_arcsine.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_arcsin_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + _ = np.arcsin(a) + assert counter.flops == 30 # 10 flops * 3 elements + + +def test_arcsin_broadcasting(): + counter = FlopCounter() + with counter: + a = 2 + _ = np.arcsin(a) + assert counter.flops == 10 # 10 flops * 1 element + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.arcsin(a) + assert counter.flops == 40 # 10 flops * 4 elements + + +def test_arcsin_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.arcsin(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_arcsin_ufunc_syntax() + test_arcsin_broadcasting() + test_arcsin_empty() diff --git a/floppy/tests/test_arctangent.py b/floppy/tests/test_arctangent.py new file mode 100644 index 0000000..e4dd90e --- /dev/null +++ b/floppy/tests/test_arctangent.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_arctangent.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_arctan_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + _ = np.arctan(a) + assert counter.flops == 30 # 10 flops * 3 elements + + +def test_arctan_broadcasting(): + counter = FlopCounter() + with counter: + a = 2 + _ = np.arctan(a) + assert counter.flops == 10 # 10 flops * 1 element + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.arctan(a) + assert counter.flops == 40 # 10 flops * 4 elements + + +def test_arctan_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.arctan(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_arctan_ufunc_syntax() + test_arctan_broadcasting() + test_arctan_empty() diff --git a/floppy/tests/test_argminmax.py b/floppy/tests/test_argminmax.py new file mode 100644 index 0000000..e2bddd2 --- /dev/null +++ b/floppy/tests/test_argminmax.py @@ -0,0 +1,79 @@ +"""Run using python tests/test_argminmax.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_argmin_basic(): + counter = FlopCounter() + with counter: + a = np.array([4, 2, 3, 1]) + _ = np.argmin(a) + assert counter.flops == 3 # n-1 comparisons for n elements + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.argmin(a) + assert counter.flops == 3 # 4 elements, 3 comparisons + + +def test_argmin_axis(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2, 3], [4, 5, 6]]) + _ = np.argmin(a, axis=0) # Compare elements in each column + assert counter.flops == 3 # 1 comparison per column + + counter.flops = 0 + with counter: + _ = np.argmin(a, axis=1) # Compare elements in each row + assert counter.flops == 4 # 2 comparisons per row + + +def test_argmax_basic(): + counter = FlopCounter() + with counter: + a = np.array([4, 2, 3, 1]) + _ = np.argmax(a) + assert counter.flops == 3 # n-1 comparisons for n elements + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.argmax(a) + assert counter.flops == 3 # 4 elements, 3 comparisons + + +def test_argmax_axis(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2, 3], [4, 5, 6]]) + _ = np.argmax(a, axis=0) # Compare elements in each column + assert counter.flops == 3 # 1 comparison per column + + counter.flops = 0 + with counter: + _ = np.argmax(a, axis=1) # Compare elements in each row + assert counter.flops == 4 # 2 comparisons per row + + +def test_argminmax_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.argmin(a) + assert counter.flops == 0 + + counter.flops = 0 + with counter: + _ = np.argmax(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_argmin_basic() + test_argmin_axis() + test_argmax_basic() + test_argmax_axis() + test_argminmax_empty() diff --git a/floppy/tests/test_bitwise_and.py b/floppy/tests/test_bitwise_and.py new file mode 100644 index 0000000..d094b30 --- /dev/null +++ b/floppy/tests/test_bitwise_and.py @@ -0,0 +1,54 @@ +"""Run using python tests/test_bitwise_and.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_bitwise_and_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a & b + assert counter.flops == 3 + + +def test_bitwise_and_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.bitwise_and(a, b) + assert counter.flops == 3 + + +def test_bitwise_and_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a &= b + assert counter.flops == 3 + + +def test_bitwise_and_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a & b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b & a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_bitwise_and_operator_syntax() + test_bitwise_and_ufunc_syntax() + test_bitwise_and_augmented_assignment() + test_bitwise_and_broadcasting() diff --git a/floppy/tests/test_bitwise_or.py b/floppy/tests/test_bitwise_or.py new file mode 100644 index 0000000..0c944c2 --- /dev/null +++ b/floppy/tests/test_bitwise_or.py @@ -0,0 +1,54 @@ +"""Run using python tests/test_bitwise_or.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_bitwise_or_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a | b + assert counter.flops == 3 + + +def test_bitwise_or_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.bitwise_or(a, b) + assert counter.flops == 3 + + +def test_bitwise_or_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a |= b + assert counter.flops == 3 + + +def test_bitwise_or_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a | b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b | a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_bitwise_or_operator_syntax() + test_bitwise_or_ufunc_syntax() + test_bitwise_or_augmented_assignment() + test_bitwise_or_broadcasting() diff --git a/floppy/tests/test_cosine.py b/floppy/tests/test_cosine.py new file mode 100644 index 0000000..e5733c9 --- /dev/null +++ b/floppy/tests/test_cosine.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_cosine.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_cos_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + _ = np.cos(a) + assert counter.flops == 24 # 8 flops * 3 elements + + +def test_cos_broadcasting(): + counter = FlopCounter() + with counter: + a = 2 + _ = np.cos(a) + assert counter.flops == 8 # 8 flops * 1 element + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.cos(a) + assert counter.flops == 32 # 8 flops * 4 elements + + +def test_cos_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.cos(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_cos_ufunc_syntax() + test_cos_broadcasting() + test_cos_empty() diff --git a/floppy/tests/test_cross.py b/floppy/tests/test_cross.py new file mode 100644 index 0000000..cb83c90 --- /dev/null +++ b/floppy/tests/test_cross.py @@ -0,0 +1,49 @@ +"""Run using python tests/test_cross.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_cross_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 0, 0]) + b = np.array([0, 1, 0]) + _ = np.cross(a, b) + assert counter.flops == 9 # 9 flops for one cross product + + +def test_cross_multiple(): + counter = FlopCounter() + with counter: + # Multiple cross products at once + a = np.array([[1, 0, 0], [2, 0, 0]]) + b = np.array([[0, 1, 0], [0, 2, 0]]) + _ = np.cross(a, b) + assert counter.flops == 18 # 9 flops * 2 cross products + + +def test_cross_broadcasting(): + counter = FlopCounter() + with counter: + # Broadcasting a single vector against multiple vectors + a = np.array([1, 0, 0]) + b = np.array([[0, 1, 0], [0, 2, 0], [0, 3, 0]]) + _ = np.cross(a, b) + assert counter.flops == 27 # 9 flops * 3 cross products + + +def test_cross_empty(): + counter = FlopCounter() + with counter: + a = np.array([]).reshape(0, 3) + b = np.array([]).reshape(0, 3) + _ = np.cross(a, b) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_cross_basic() + test_cross_multiple() + test_cross_broadcasting() + test_cross_empty() diff --git a/floppy/tests/test_divide.py b/floppy/tests/test_divide.py new file mode 100644 index 0000000..984b000 --- /dev/null +++ b/floppy/tests/test_divide.py @@ -0,0 +1,64 @@ +"""Run using python tests/test_divide.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_divide_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a / b + assert counter.flops == 3 + + +def test_divide_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.divide(a, b) + assert counter.flops == 3 + + +def test_divide_method_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a.divide(b) + assert counter.flops == 3 + + +def test_divide_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a /= b + assert counter.flops == 3 + + +def test_divide_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a / b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b / a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_divide_operator_syntax() + test_divide_ufunc_syntax() + # test_divide_method_syntax() # Expected to fail + test_divide_augmented_assignment() + test_divide_broadcasting() diff --git a/floppy/tests/test_dot.py b/floppy/tests/test_dot.py new file mode 100644 index 0000000..a925b41 --- /dev/null +++ b/floppy/tests/test_dot.py @@ -0,0 +1,81 @@ +"""Run using python tests/test_dot.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_dot_np_function(): + counter = FlopCounter() + with counter: + # Vector dot product + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.dot(a, b) + assert counter.flops == 5 # 3 multiplications + 2 additions + + +def test_dot_method(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a.dot(b) + assert counter.flops == 5 + + +def test_dot_matrix_vector(): + counter = FlopCounter() + with counter: + # (2x3) @ (3,) + a = np.array([[1, 2, 3], [4, 5, 6]]) + b = np.array([7, 8, 9]) + _ = np.dot(a, b) + assert counter.flops == 10 # 2 rows * (3 muls + 2 adds) + + +def test_dot_matrix_matrix(): + counter = FlopCounter() + with counter: + # (2x2) @ (2x2) + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + _ = np.dot(a, b) + assert counter.flops == 12 # 4 elements * (2 muls + 1 add) + + +def test_dot_different_sizes(): + counter = FlopCounter() + with counter: + # (2x3) @ (3x2) + a = np.array([[1, 2, 3], [4, 5, 6]]) + b = np.array([[7, 8], [9, 10], [11, 12]]) + _ = np.dot(a, b) + assert counter.flops == 20 # 4 elements * (3 muls + 2 adds) + + +def test_dot_1d_scalar(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = np.dot(a, b) + assert counter.flops == 3 # 3 multiplications, no additions + + +def test_dot_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + b = np.array([]) + _ = np.dot(a, b) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_dot_np_function() + test_dot_method() + test_dot_matrix_vector() + test_dot_matrix_matrix() + test_dot_different_sizes() + test_dot_1d_scalar() + test_dot_empty() diff --git a/floppy/tests/test_floor_divide.py b/floppy/tests/test_floor_divide.py new file mode 100644 index 0000000..1ab852f --- /dev/null +++ b/floppy/tests/test_floor_divide.py @@ -0,0 +1,54 @@ +"""Run using python tests/test_floor_divide.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_floor_divide_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a // b + assert counter.flops == 3 + + +def test_floor_divide_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.floor_divide(a, b) + assert counter.flops == 3 + + +def test_floor_divide_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a //= b + assert counter.flops == 3 + + +def test_floor_divide_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a // b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b // a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_floor_divide_operator_syntax() + test_floor_divide_ufunc_syntax() + test_floor_divide_augmented_assignment() + test_floor_divide_broadcasting() diff --git a/floppy/tests/test_isnan.py b/floppy/tests/test_isnan.py new file mode 100644 index 0000000..a84e063 --- /dev/null +++ b/floppy/tests/test_isnan.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_isnan.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_isnan_basic(): + counter = FlopCounter() + with counter: + a = np.array([1.0, np.nan, 3.0]) + _ = np.isnan(a) + assert counter.flops == 3 # 1 flop per element + + +def test_isnan_broadcasting(): + counter = FlopCounter() + with counter: + a = np.nan + _ = np.isnan(a) + assert counter.flops == 1 + + counter.flops = 0 + with counter: + a = np.array([[1.0, np.nan], [3.0, np.nan]]) + _ = np.isnan(a) + assert counter.flops == 4 + + +def test_isnan_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.isnan(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_isnan_basic() + test_isnan_broadcasting() + test_isnan_empty() diff --git a/floppy/tests/test_linalg.py b/floppy/tests/test_linalg.py new file mode 100644 index 0000000..ff7cd5e --- /dev/null +++ b/floppy/tests/test_linalg.py @@ -0,0 +1,141 @@ +"""Run using python tests/test_linalg.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_norm_vector(): + counter = FlopCounter() + with counter: + # Vector norm (Frobenius/L2 norm) + a = np.array([1, 2, 3, 4]) + _ = np.linalg.norm(a) + assert counter.flops == 8 # 2n FLOPs for n elements + + +def test_norm_matrix(): + counter = FlopCounter() + with counter: + # Matrix Frobenius norm + a = np.array([[1, 2], [3, 4]]) + _ = np.linalg.norm(a) + assert counter.flops == 8 # 2n FLOPs for n total elements + + +def test_norm_different_ord(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.linalg.norm(a, ord=2) # L2 norm + assert counter.flops == 8 + + counter.flops = 0 + with counter: + _ = np.linalg.norm(a, ord=np.inf) # Max norm + assert counter.flops == 8 # Should still count as 2n FLOPs + + +def test_cond_basic(): + counter = FlopCounter() + with counter: + # 2x2 matrix condition number + a = np.array([[1, 2], [3, 4]]) + _ = np.linalg.cond(a) + assert counter.flops == 14 * 2**3 + 1 # 14n³ + 1 FLOPs for nxn matrix + + +def test_cond_different_norm(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.linalg.cond(a, p="fro") + assert counter.flops == 14 * 2**3 + 1 + + +def test_inv_basic(): + counter = FlopCounter() + with counter: + # 2x2 matrix inversion + a = np.array([[1, 2], [3, 4]]) + _ = np.linalg.inv(a) + assert counter.flops == (2 * 2**3) // 3 + 2 * 2**2 # 2/3 n³ + 2n² FLOPs + + +def test_inv_method(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.matrix(a).I # Matrix inverse using matrix class + assert counter.flops == (2 * 2**3) // 3 + 2 * 2**2 + + +def test_eig_basic(): + counter = FlopCounter() + with counter: + # 2x2 eigendecomposition + a = np.array([[1, 2], [3, 4]]) + _ = np.linalg.eig(a) + assert counter.flops == 22 * 2**3 # 22n³ FLOPs + + +def test_eig_symmetric(): + counter = FlopCounter() + with counter: + # Symmetric 2x2 matrix + a = np.array([[1, 2], [2, 4]]) + _ = np.linalg.eigh(a) # Using eigh for symmetric matrices + assert counter.flops == 22 * 2**3 # Should count same as regular eig + + +def test_larger_matrices(): + n = 4 + counter = FlopCounter() + + # Test norm + with counter: + a = np.random.rand(n, n) + _ = np.linalg.norm(a) + assert counter.flops == 2 * n * n # 2n FLOPs for n² elements + + # Test cond + counter.flops = 0 + with counter: + _ = np.linalg.cond(a) + assert counter.flops == 14 * n**3 + 1 + + # Test inv + counter.flops = 0 + with counter: + _ = np.linalg.inv(a) + assert counter.flops == (2 * n**3) // 3 + 2 * n**2 + + # Test eig + counter.flops = 0 + with counter: + _ = np.linalg.eig(a) + assert counter.flops == 22 * n**3 + + +def test_empty(): + counter = FlopCounter() + with counter: + a = np.array([]).reshape(0, 0) + try: + _ = np.linalg.norm(a) + except: + pass + assert counter.flops == 0 + + +if __name__ == "__main__": + test_norm_vector() + test_norm_matrix() + test_norm_different_ord() + test_cond_basic() + test_cond_different_norm() + test_inv_basic() + test_inv_method() + test_eig_basic() + test_eig_symmetric() + test_larger_matrices() + test_empty() diff --git a/floppy/tests/test_log.py b/floppy/tests/test_log.py new file mode 100644 index 0000000..6bfff1e --- /dev/null +++ b/floppy/tests/test_log.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_log.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_log_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + _ = np.log(a) + assert counter.flops == 15 # Assuming 5 flops per log operation + + +def test_log_broadcasting(): + counter = FlopCounter() + with counter: + a = 2 + _ = np.log(a) + assert counter.flops == 5 + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.log(a) + assert counter.flops == 20 # 5 flops * 4 elements + + +def test_log_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.log(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_log_basic() + test_log_broadcasting() + test_log_empty() diff --git a/floppy/tests/test_matmul.py b/floppy/tests/test_matmul.py new file mode 100644 index 0000000..d1c46a8 --- /dev/null +++ b/floppy/tests/test_matmul.py @@ -0,0 +1,106 @@ +"""Run using python tests/test_matmul.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_matmul_np_function(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + _ = np.matmul(a, b) + assert counter.flops == 12 # 4 * (2 muls + 1 add) + + +def test_matmul_operator(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + _ = a @ b + assert counter.flops == 12 + + +def test_matmul_method(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + _ = a.matmul(b) + assert counter.flops == 12 + + +def test_dot_function(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + _ = np.dot(a, b) + assert counter.flops == 12 + + +def test_dot_method(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + b = np.array([[5, 6], [7, 8]]) + _ = a.dot(b) + assert counter.flops == 12 + + +def test_different_sizes(): + counter = FlopCounter() + with counter: + # (2x3) @ (3x2) + a = np.array([[1, 2, 3], [4, 5, 6]]) + b = np.array([[7, 8], [9, 10], [11, 12]]) + _ = a @ b + assert counter.flops == 20 # 4 * (3 muls + 2 adds) + + +def test_vector_matmul(): + counter = FlopCounter() + with counter: + # Matrix @ vector + a = np.array([[1, 2], [3, 4]]) + b = np.array([5, 6]) + _ = a @ b + assert counter.flops == 6 # 2 * (2 muls + 1 add) + + counter.flops = 0 + with counter: + # vector @ Matrix + _ = b @ a + assert counter.flops == 6 + + +def test_batch_matmul(): + counter = FlopCounter() + with counter: + # Batch matrix multiplication (2 batches of 2x2) + a = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]]) + b = np.array([[[9, 10], [11, 12]], [[13, 14], [15, 16]]]) + _ = a @ b + assert counter.flops == 24 # 2 batches * 12 flops + + +def test_empty(): + counter = FlopCounter() + with counter: + a = np.array([]).reshape(0, 0) + b = np.array([]).reshape(0, 0) + _ = a @ b + assert counter.flops == 0 + + +if __name__ == "__main__": + test_matmul_np_function() + test_matmul_operator() + test_matmul_method() + test_dot_function() + test_dot_method() + test_different_sizes() + test_vector_matmul() + test_batch_matmul() + test_empty() diff --git a/floppy/tests/test_minmax.py b/floppy/tests/test_minmax.py new file mode 100644 index 0000000..ba97834 --- /dev/null +++ b/floppy/tests/test_minmax.py @@ -0,0 +1,51 @@ +"""Run using python tests/test_minmax.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_min_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.min(a) + assert counter.flops == 3 # n-1 comparisons for n elements + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.min(a) + assert counter.flops == 3 + + +def test_max_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.max(a) + assert counter.flops == 3 # n-1 comparisons for n elements + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.max(a) + assert counter.flops == 3 + + +def test_minmax_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.min(a) + assert counter.flops == 0 + + counter.flops = 0 + with counter: + _ = np.max(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_min_basic() + test_max_basic() + test_minmax_empty() diff --git a/floppy/tests/test_mod.py b/floppy/tests/test_mod.py new file mode 100644 index 0000000..acdf46e --- /dev/null +++ b/floppy/tests/test_mod.py @@ -0,0 +1,54 @@ +"""Run using python tests/test_mod.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_mod_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a % b + assert counter.flops == 3 + + +def test_mod_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.mod(a, b) + assert counter.flops == 3 + + +def test_mod_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a %= b + assert counter.flops == 3 + + +def test_mod_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a % b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b % a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_mod_operator_syntax() + test_mod_ufunc_syntax() + test_mod_augmented_assignment() + test_mod_broadcasting() diff --git a/floppy/tests/test_multiply.py b/floppy/tests/test_multiply.py new file mode 100644 index 0000000..c1592a4 --- /dev/null +++ b/floppy/tests/test_multiply.py @@ -0,0 +1,64 @@ +"""Run using python tests/test_multiply.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_multiply_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a * b + assert counter.flops == 3 + + +def test_multiply_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.multiply(a, b) + assert counter.flops == 3 + + +def test_multiply_method_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a.multiply(b) + assert counter.flops == 3 + + +def test_multiply_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a *= b + assert counter.flops == 3 + + +def test_multiply_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a * b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b * a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_multiply_operator_syntax() + test_multiply_ufunc_syntax() + # test_multiply_method_syntax() # Expected to fail + test_multiply_augmented_assignment() + test_multiply_broadcasting() diff --git a/floppy/tests/test_power.py b/floppy/tests/test_power.py new file mode 100644 index 0000000..a9b01c8 --- /dev/null +++ b/floppy/tests/test_power.py @@ -0,0 +1,64 @@ +"""Run using python tests/test_power.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_power_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a**b + assert counter.flops == 3 + + +def test_power_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.power(a, b) + assert counter.flops == 3 + + +def test_power_method_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a.power(b) + assert counter.flops == 3 + + +def test_power_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a **= b + assert counter.flops == 3 + + +def test_power_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a**b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b**a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_power_operator_syntax() + test_power_ufunc_syntax() + # test_power_method_syntax() # Expected to fail + test_power_augmented_assignment() + test_power_broadcasting() diff --git a/floppy/tests/test_round.py b/floppy/tests/test_round.py new file mode 100644 index 0000000..8641359 --- /dev/null +++ b/floppy/tests/test_round.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_round.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_round_basic(): + counter = FlopCounter() + with counter: + a = np.array([1.4, 2.6, 3.5]) + _ = np.round(a) + assert counter.flops == 3 # 1 flop per element + + +def test_round_broadcasting(): + counter = FlopCounter() + with counter: + a = 2.5 + _ = np.round(a) + assert counter.flops == 1 + + counter.flops = 0 + with counter: + a = np.array([[1.4, 2.6], [3.5, 4.1]]) + _ = np.round(a) + assert counter.flops == 4 + + +def test_round_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.round(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_round_basic() + test_round_broadcasting() + test_round_empty() diff --git a/floppy/tests/test_sine.py b/floppy/tests/test_sine.py new file mode 100644 index 0000000..ba9a06b --- /dev/null +++ b/floppy/tests/test_sine.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_sin.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_sin_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + _ = np.sin(a) + assert counter.flops == 24 + + +def test_sin_broadcasting(): + counter = FlopCounter() + with counter: + a = 2 + _ = np.sin(a) + assert counter.flops == 8 + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.sin(a) + assert counter.flops == 32 + + +def test_sin_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.sin(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_sin_ufunc_syntax() + test_sin_broadcasting() + test_sin_empty() diff --git a/floppy/tests/test_stats.py b/floppy/tests/test_stats.py new file mode 100644 index 0000000..f7f596d --- /dev/null +++ b/floppy/tests/test_stats.py @@ -0,0 +1,178 @@ +"""Run using python tests/test_stats.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_mean_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.mean(a) + assert counter.flops == 4 # n-1 adds + 1 division + + +def test_mean_method(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = a.mean() + assert counter.flops == 4 + + +def test_mean_axis(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2, 3], [4, 5, 6]]) + _ = np.mean(a, axis=0) # Column means + assert counter.flops == 6 # 3 columns * (1 add + 1 div) + + counter.flops = 0 + with counter: + _ = np.mean(a, axis=1) # Row means + assert counter.flops == 8 # 2 rows * (2 adds + 1 div) + + +def test_std_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.std(a) + # For n elements: + # - n-1 adds + 1 div for mean + # - n subtractions from mean + # - n multiplications for square + # - n-1 adds for sum + # - 1 division by (n-1) + # - 1 sqrt + assert counter.flops == 19 # 4 + 4 + 4 + 3 + 1 + 3 + + +def test_std_method(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = a.std() + assert counter.flops == 19 + + +def test_var_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.var(a) + # Same as std but without sqrt + assert counter.flops == 16 # 4 + 4 + 4 + 3 + 1 + + +def test_var_method(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = a.var() + assert counter.flops == 16 + + +def test_average_basic(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.average(a) + assert counter.flops == 4 # Same as mean + + +def test_average_weighted(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + weights = np.array([1, 1, 1, 1]) + _ = np.average(a, weights=weights) + # For n elements: + # - n multiplications for weights + # - n-1 adds for numerator + # - n-1 adds for denominator + # - 1 division + assert counter.flops == 11 # 4 + 3 + 3 + 1 + + +def test_trace_basic(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.trace(a) + assert counter.flops == 1 # n-1 adds for n diagonal elements + + +def test_trace_method(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = a.trace() + assert counter.flops == 1 + + +def test_trace_offset(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]]) + _ = np.trace(a, offset=1) # Sum of [2, 6] + assert counter.flops == 1 + + +def test_stats_axis_params(): + counter = FlopCounter() + a = np.array([[1, 2, 3], [4, 5, 6]]) + + # Test std along axis + with counter: + _ = np.std(a, axis=0) + assert counter.flops == 27 # 3 columns * 9 flops per std + + counter.flops = 0 + with counter: + _ = np.std(a, axis=1) + assert counter.flops == 38 # 2 rows * 19 flops per std + + # Test var along axis + counter.flops = 0 + with counter: + _ = np.var(a, axis=0) + assert counter.flops == 24 # 3 columns * 8 flops per var + + +def test_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.mean(a) + assert counter.flops == 0 + + _ = np.std(a) + assert counter.flops == 0 + + _ = np.var(a) + assert counter.flops == 0 + + _ = np.average(a) + assert counter.flops == 0 + + b = np.array([]).reshape(0, 0) + _ = np.trace(b) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_mean_basic() + test_mean_method() + test_mean_axis() + test_std_basic() + test_std_method() + test_var_basic() + test_var_method() + test_average_basic() + test_average_weighted() + test_trace_basic() + test_trace_method() + test_trace_offset() + test_stats_axis_params() + test_empty() diff --git a/floppy/tests/test_subtract.py b/floppy/tests/test_subtract.py new file mode 100644 index 0000000..bf6f0f9 --- /dev/null +++ b/floppy/tests/test_subtract.py @@ -0,0 +1,64 @@ +"""Run using python tests/test_subtract.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_subtract_operator_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a - b + assert counter.flops == 3 + + +def test_subtract_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = np.subtract(a, b) + assert counter.flops == 3 + + +def test_subtract_method_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + _ = a.subtract(b) + assert counter.flops == 3 + + +def test_subtract_augmented_assignment(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = np.array([4, 5, 6]) + a -= b + assert counter.flops == 3 + + +def test_subtract_broadcasting(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = a - b + assert counter.flops == 3 + + counter.flops = 0 + with counter: + a = np.array([1, 2, 3]) + b = 2 + _ = b - a + assert counter.flops == 3 + + +if __name__ == "__main__": + test_subtract_operator_syntax() + test_subtract_ufunc_syntax() + # test_subtract_method_syntax() # Expected to fail + test_subtract_augmented_assignment() + test_subtract_broadcasting() diff --git a/floppy/tests/test_sum.py b/floppy/tests/test_sum.py new file mode 100644 index 0000000..1c03b0e --- /dev/null +++ b/floppy/tests/test_sum.py @@ -0,0 +1,67 @@ +"""Run using python tests/test_sum.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_sum_np_function(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = np.sum(a) + assert counter.flops == 3 # n-1 additions for n elements + + +def test_sum_method(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + _ = a.sum() + assert counter.flops == 3 + + +def test_sum_axis(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2, 3], [4, 5, 6]]) + _ = np.sum(a, axis=0) # Sum columns + assert counter.flops == 2 # 1 addition per column * 3 columns + + counter.flops = 0 + with counter: + _ = np.sum(a, axis=1) # Sum rows + assert counter.flops == 4 # 2 additions per row * 2 rows + + +def test_sum_keepdims(): + counter = FlopCounter() + with counter: + a = np.array([[1, 2, 3], [4, 5, 6]]) + _ = np.sum(a, keepdims=True) + assert counter.flops == 5 # 6 elements - 1 addition + + +def test_sum_where(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3, 4]) + mask = np.array([True, False, True, False]) + _ = np.sum(a, where=mask) + assert counter.flops == 1 # Only one addition needed for two True values + + +def test_sum_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.sum(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_sum_np_function() + # test_sum_method() + test_sum_axis() + test_sum_keepdims() + test_sum_where() + test_sum_empty() diff --git a/floppy/tests/test_tangent.py b/floppy/tests/test_tangent.py new file mode 100644 index 0000000..aab551c --- /dev/null +++ b/floppy/tests/test_tangent.py @@ -0,0 +1,40 @@ +"""Run using python tests/test_tangent.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_tan_ufunc_syntax(): + counter = FlopCounter() + with counter: + a = np.array([1, 2, 3]) + _ = np.tan(a) + assert counter.flops == 51 # 17 flops * 3 elements + + +def test_tan_broadcasting(): + counter = FlopCounter() + with counter: + a = 2 + _ = np.tan(a) + assert counter.flops == 17 # 17 flops * 1 element + + counter.flops = 0 + with counter: + a = np.array([[1, 2], [3, 4]]) + _ = np.tan(a) + assert counter.flops == 68 # 17 flops * 4 elements + + +def test_tan_empty(): + counter = FlopCounter() + with counter: + a = np.array([]) + _ = np.tan(a) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_tan_ufunc_syntax() + test_tan_broadcasting() + test_tan_empty() diff --git a/floppy/tests/test_where.py b/floppy/tests/test_where.py new file mode 100644 index 0000000..38a4bc0 --- /dev/null +++ b/floppy/tests/test_where.py @@ -0,0 +1,48 @@ +"""Run using python tests/test_where.py. Do not use pytest.""" + +import numpy as np +from floppy.flop_counting.counter import FlopCounter + + +def test_where_basic(): + counter = FlopCounter() + with counter: + condition = np.array([True, False, True]) + x = np.array([1, 2, 3]) + y = np.array([4, 5, 6]) + _ = np.where(condition, x, y) + assert counter.flops == 3 # 1 flop per element for selection + + +def test_where_broadcasting(): + counter = FlopCounter() + with counter: + condition = np.array([[True, False], [False, True]]) + x = 1 + y = 0 + _ = np.where(condition, x, y) + assert counter.flops == 4 # 1 flop per element + + counter.flops = 0 + with counter: + condition = True + x = np.array([[1, 2], [3, 4]]) + y = 0 + _ = np.where(condition, x, y) + assert counter.flops == 4 + + +def test_where_empty(): + counter = FlopCounter() + with counter: + condition = np.array([]) + x = np.array([]) + y = np.array([]) + _ = np.where(condition, x, y) + assert counter.flops == 0 + + +if __name__ == "__main__": + test_where_basic() + test_where_broadcasting() + test_where_empty() diff --git a/monty_flops/README.md b/monty_flops/README.md deleted file mode 100644 index 534096a..0000000 --- a/monty_flops/README.md +++ /dev/null @@ -1,17 +0,0 @@ -# Computing FLOPs in Monty - -Using `pypapi` to compute FLOPs in Monty. -Note that `pypapi` only works on Linux (Oracle Node). - -1. Create a new conda environment in Linux (Oracle Node). - -```bash -conda create -n monty_flops python=3.9 -conda activate monty_flops -``` - -2. Install `pypapi`. - -```bash -pip install python-papi -```