From d09aaa2a4f0cb0041db04254d93701d989e1ee0f Mon Sep 17 00:00:00 2001 From: Erick Fuentes Date: Wed, 2 Jul 2025 15:39:23 -0400 Subject: [PATCH] wip --- .../overhead_matching/swag/scripts/BUILD | 20 +++ .../aws/src/evaluate_model_on_paths.py | 49 ++++++++ .../swag/scripts/evaluate_model_on_paths.py | 115 +++++++++++++----- 3 files changed, 153 insertions(+), 31 deletions(-) create mode 100644 experimental/overhead_matching/swag/scripts/aws/src/evaluate_model_on_paths.py diff --git a/experimental/overhead_matching/swag/scripts/BUILD b/experimental/overhead_matching/swag/scripts/BUILD index fd3cbe40c..b9ec0fd22 100644 --- a/experimental/overhead_matching/swag/scripts/BUILD +++ b/experimental/overhead_matching/swag/scripts/BUILD @@ -68,6 +68,26 @@ py_binary( ] ) +py_package( + name = "evaluate_model_on_paths_package", + deps = [":evaluate_model_on_paths"], +) + +py_wheel( + name = "evaluate_model_on_paths_wheel", + distribution="overhead_matching_evaluate_model_on_paths", + version = "0.0.1", + platform = "manylinux2014_x86_64", + tags = ["manual"], + python_tag = select({ + "@rules_python//python/config_settings:is_python_3.12": "cp312" + }), + abi = select({ + "@rules_python//python/config_settings:is_python_3.12": "cp312" + }), + deps = [":evaluate_model_on_paths_package"], +) + py_binary( name="plot_path_evaluations", srcs=["plot_path_evaluations.py"], diff --git a/experimental/overhead_matching/swag/scripts/aws/src/evaluate_model_on_paths.py b/experimental/overhead_matching/swag/scripts/aws/src/evaluate_model_on_paths.py new file mode 100644 index 000000000..152415cc5 --- /dev/null +++ b/experimental/overhead_matching/swag/scripts/aws/src/evaluate_model_on_paths.py @@ -0,0 +1,49 @@ + +import subprocess +import sys +import logging +from pathlib import Path +import os +import boto3 +from urllib.parse import urlparse +import glob + + +def install_s3_wheel(s3_uri): + """Download and install wheel from S3""" + # Parse S3 URI + parsed = urlparse(s3_uri) + if parsed.scheme == "s3": + bucket = parsed.netloc + key = parsed.path.lstrip('/') + # Download wheel + s3_client = boto3.client('s3') + local_wheel_path = f'/tmp/{key.split("/")[-1]}' + s3_client.download_file(bucket, key, local_wheel_path) + else: + local_wheel_path = parsed.path + # Install wheel + subprocess.check_call([sys.executable, '-m', 'pip', 'install', '--force-reinstall', local_wheel_path]) + + # This is a hack due to bazel wheels packaging dependencies in another site-packages directory + to_add = [] + for p in sys.path: + p = Path(p) + maybe_to_add = p / 'site-packages' + if maybe_to_add.exists(): + to_add.append(str(maybe_to_add)) + sys.path.extend(to_add) + + +wheel_s3_uri = os.environ.get("CUSTOM_WHEEL_S3_URI") +install_s3_wheel(wheel_s3_uri) + +import experimental.overhead_matching.swag.scripts.evaluate_model_on_paths as emops + +train_config_path = glob.glob("/opt/ml/input/data/config_file/*.yaml")[0] +t.main(dataset_path=Path("/opt/ml/input/data/train"), + opt_config_path=Path(train_config_path), + output_dir=Path("/opt/ml/model"), + tensorboard_output=Path("/opt/ml/output/tensorboard"), + quiet=True) + diff --git a/experimental/overhead_matching/swag/scripts/evaluate_model_on_paths.py b/experimental/overhead_matching/swag/scripts/evaluate_model_on_paths.py index 5db98b13e..449450cae 100644 --- a/experimental/overhead_matching/swag/scripts/evaluate_model_on_paths.py +++ b/experimental/overhead_matching/swag/scripts/evaluate_model_on_paths.py @@ -33,6 +33,77 @@ def construct_path_eval_inputs_from_args( return vigor_dataset, sat_model, pano_model, paths_data +def main( + output_path: Path, + sat_model_path: Path, + pano_model_path: Path, + dataset_path: Path, + paths_path: Path, + panorama_neighbor_radius_deg: float, + dual_mcl_frac: float, + dual_mcl_phantom_counts_frac: float, + save_intermediate_filter_states: float, + seed: int, + ): + DEVICE = "cuda:0" + torch.set_deterministic_debug_mode('error') + + output_path.mkdir(parents=True, exist_ok=True) + with open(Path(output_path) / "args.json", "w") as f: + json.dump({ + "output_path": str(output_path), + "sat_model_path": str(sat_model_path), + "pano_model_path": str(pano_model_path), + "dataset_path": str(dataset_path), + "paths_path": str(paths_path), + "panorama_neighbor_radius_deg": panorama_neighbor_radius_deg, + "dual_mcl_frac": dual_mcl_frac, + "dual_mcl_phantom_counts_frac": dual_mcl_phantom_counts_frac, + "save_intermediate_filter_states": save_intermediate_filter_states, + "seed": seed}, f, indent=4) + + vigor_dataset, sat_model, pano_model, paths_data = construct_path_eval_inputs_from_args( + sat_model_path=sat_model_path, + pano_model_path=pano_model_path, + dataset_path=dataset_path, + paths_path=paths_path, + panorama_neighbor_radius_deg=panorama_neighbor_radius_deg, + ) + + def degrees_from_meters(dist_m): + EARTH_RADIUS_M = 6_371_000.0 + return math.degrees(dist_m / EARTH_RADIUS_M) + + wag_config = WagConfig(noise_percent_motion_model=0.02, # page 71 thesis + # offset was fixed at 1.3km in thesis (page 71) + initial_particle_distribution_offset_std_deg=degrees_from_meters(1300.0), + # page 73 of thesis + initial_particle_distribution_std_deg=degrees_from_meters(2970.0), + num_particles=100_000, + sigma_obs_prob_from_sim=0.1, + satellite_patch_config=SatellitePatchConfig( + zoom_level=20, + patch_height_px=640, + patch_width_px=640), + dual_mcl_frac=dual_mcl_frac, + dual_mcl_belief_phantom_counts_frac=dual_mcl_phantom_counts_frac) + + with open(Path(output_path) / "wag_config.pbtxt", "w") as f: + f.write(text_format.MessageToString(wag_config)) + + es.evaluate_model_on_paths( + vigor_dataset=vigor_dataset, + sat_model=sat_model, + pano_model=pano_model, + paths=paths_data['paths'], + wag_config=wag_config, + seed=seed, + output_path=output_path, + device=DEVICE, + save_intermediate_filter_states=save_intermediate_filter_states + ) + + if __name__ == "__main__": import argparse @@ -57,6 +128,7 @@ def construct_path_eval_inputs_from_args( args = parser.parse_args() +<<<<<<< Updated upstream # torch.cuda.memory._record_memory_history(max_entries=100_000) DEVICE = "cuda:0" @@ -75,38 +147,19 @@ def construct_path_eval_inputs_from_args( pano_model_path=args.pano_model_path, dataset_path=args.dataset_path, paths_path=args.paths_path, +======= + main( + output_path=Path(args.output_path), + sat_model_path=Path(args.sat_path), + pano_model_path=Path(args.pano_path), + dataset_path=Path(args.dataset_path), + paths_path=Path(args.paths_path), +>>>>>>> Stashed changes panorama_neighbor_radius_deg=args.panorama_neighbor_radius_deg, + dual_mcl_frac=args.dual_mcl_frac, + dual_mcl_phantom_counts_frac=args.dual_mcl_phantom_counts_frac, + save_intermediate_filter_states=args.save_intermediate_filter_states, + seed=args.seed ) - def degrees_from_meters(dist_m): - EARTH_RADIUS_M = 6_371_000.0 - return math.degrees(dist_m / EARTH_RADIUS_M) - wag_config = WagConfig(noise_percent_motion_model=0.02, # page 71 thesis - # offset was fixed at 1.3km in thesis (page 71) - initial_particle_distribution_offset_std_deg=degrees_from_meters(1300.0), - # page 73 of thesis - initial_particle_distribution_std_deg=degrees_from_meters(2970.0), - num_particles=100_000, - sigma_obs_prob_from_sim=0.1, - satellite_patch_config=SatellitePatchConfig( - zoom_level=20, - patch_height_px=640, - patch_width_px=640), - dual_mcl_frac=args.dual_mcl_frac, - dual_mcl_belief_phantom_counts_frac=args.dual_mcl_phantom_counts_frac) - - with open(Path(args.output_path) / "wag_config.pbtxt", "w") as f: - f.write(text_format.MessageToString(wag_config)) - - es.evaluate_model_on_paths( - vigor_dataset=vigor_dataset, - sat_model=sat_model, - pano_model=pano_model, - paths=paths_data['paths'], - wag_config=wag_config, - seed=args.seed, - output_path=args.output_path, - device=DEVICE, - save_intermediate_filter_states=args.save_intermediate_filter_states - )