From f29ea5b5a3b945ac1679573b5a7791a1ecd17811 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=C3=A9rian=20Rey?= Date: Thu, 21 May 2026 01:04:26 +0200 Subject: [PATCH 1/2] refactor(tests): Move results folders inside tests/ subdirectories - static_plotter now saves to tests/plots/results/ instead of images/ - profiler now saves to tests/profiling/results/ instead of traces/ - Rename TRACES_DIR to PROFILING_RESULTS_DIR and add TESTS_DIR in tests/paths.py - Update .gitignore accordingly Co-Authored-By: Claude Sonnet 4.6 --- .gitignore | 4 ++-- tests/paths.py | 3 ++- tests/plots/static_plotter.py | 9 +++++---- tests/profiling/plot_memory_timeline.py | 6 +++--- tests/profiling/run_profiler.py | 4 ++-- 5 files changed, 14 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 70e4cbd7c..50db3c6d3 100644 --- a/.gitignore +++ b/.gitignore @@ -2,7 +2,7 @@ CLAUDE.md # Profiling results -traces/ +tests/profiling/results/ # Trajectories results tests/trajectories/results/ @@ -17,7 +17,7 @@ uv.lock .idea/ # Generated images -images/ +tests/plots/results/ # Byte-compiled / optimized / DLL files __pycache__/ diff --git a/tests/paths.py b/tests/paths.py index 0ed56e2dd..754bbaa1d 100644 --- a/tests/paths.py +++ b/tests/paths.py @@ -1,4 +1,5 @@ from pathlib import Path TORCHJD_DIR = Path(__file__).parent.parent -TRACES_DIR = TORCHJD_DIR / "traces" +TESTS_DIR = Path(__file__).parent +PROFILING_RESULTS_DIR = TESTS_DIR / "profiling" / "results" diff --git a/tests/plots/static_plotter.py b/tests/plots/static_plotter.py index de5d68369..87c3abdbe 100644 --- a/tests/plots/static_plotter.py +++ b/tests/plots/static_plotter.py @@ -1,4 +1,4 @@ -import os +from pathlib import Path import torch from plotly import graph_objects as go @@ -268,14 +268,15 @@ def main( ) fig.update_yaxes(range=[-0.1, 2.1], showgrid=False, zeroline=False, visible=False) - os.makedirs("images/", exist_ok=True) - fig.write_image(f"images/{filename}.pdf") + results_dir = Path(__file__).parent / "results" + results_dir.mkdir(exist_ok=True) + fig.write_image(results_dir / f"{filename}.pdf") # Alternative: use .svg here and then convert to pdf using rsvg-convert. Install # [rsvg-convert](https://manpages.ubuntu.com/manpages/bionic/man1/rsvg-convert.1.html) and run: # `rsvg-convert -f pdf -o filename.pdf filename.svg` # To do that on all files at ones, run: # ``` - # for file in images/*.svg; do rsvg-convert -f pdf -o "${file%.svg}.pdf" "$file"; done + # for file in tests/plots/results/*.svg; do rsvg-convert -f pdf -o "${file%.svg}.pdf" "$file"; done # ``` diff --git a/tests/profiling/plot_memory_timeline.py b/tests/profiling/plot_memory_timeline.py index 4c2d94390..398dbc1ed 100644 --- a/tests/profiling/plot_memory_timeline.py +++ b/tests/profiling/plot_memory_timeline.py @@ -13,7 +13,7 @@ matplotlib.use("Agg") # Use non-GUI backend to avoid tkinter dependency import matplotlib.pyplot as plt import numpy as np -from paths import TRACES_DIR +from paths import PROFILING_RESULTS_DIR @dataclass @@ -63,7 +63,7 @@ def plot_memory_timelines(experiment: str, folders: list[str]) -> None: cpu_timelines = [] cuda_timelines = [] for folder in folders: - path = TRACES_DIR / folder / f"{experiment}.json" + path = PROFILING_RESULTS_DIR / folder / f"{experiment}.json" cpu_timeline, cuda_timeline = extract_memory_timelines(path) cpu_timelines.append(cpu_timeline) cuda_timelines.append(cuda_timeline) @@ -104,7 +104,7 @@ def plot_memory_timelines(experiment: str, folders: list[str]) -> None: fig.tight_layout() - output_dir = Path(TRACES_DIR / "memory_timelines") + output_dir = Path(PROFILING_RESULTS_DIR / "memory_timelines") output_dir.mkdir(parents=True, exist_ok=True) output_path = output_dir / f"{experiment}.png" print(f"\nSaving plot to: {output_path}") diff --git a/tests/profiling/run_profiler.py b/tests/profiling/run_profiler.py index 9807849bb..e61faa311 100644 --- a/tests/profiling/run_profiler.py +++ b/tests/profiling/run_profiler.py @@ -23,7 +23,7 @@ ) from utils.tensors import make_inputs_and_targets -from tests.paths import TRACES_DIR +from tests.paths import PROFILING_RESULTS_DIR from torchjd.aggregation import UPGrad, UPGradWeighting from torchjd.autogram import Engine @@ -98,7 +98,7 @@ def _save_and_print_trace( batch_size: int, ) -> None: filename = f"{factory}-bs{batch_size}-{DEVICE.type}.json" - output_dir = TRACES_DIR / method_name + output_dir = PROFILING_RESULTS_DIR / method_name output_dir.mkdir(parents=True, exist_ok=True) trace_path = output_dir / filename From 331085981e4343a3b6fd74d99425a9833375f56b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Val=C3=A9rian=20Rey?= Date: Thu, 21 May 2026 01:20:39 +0200 Subject: [PATCH 2/2] refactor(tests): Add PLOTS_RESULTS_DIR, move RESULTS_DIR to paths.py - Add PLOTS_RESULTS_DIR to tests/paths.py and use it in static_plotter - Move RESULTS_DIR from trajectories/_paths.py to tests/paths.py, renamed TRAJECTORIES_RESULTS_DIR, and update all usages Co-Authored-By: Claude Sonnet 4.6 --- tests/paths.py | 2 ++ tests/plots/static_plotter.py | 8 +++----- tests/trajectories/_paths.py | 12 ++++++------ tests/trajectories/optimize.py | 5 +++-- tests/trajectories/plot_distance_to_pf.py | 5 +++-- tests/trajectories/plot_params.py | 5 +++-- tests/trajectories/plot_values.py | 5 +++-- 7 files changed, 23 insertions(+), 19 deletions(-) diff --git a/tests/paths.py b/tests/paths.py index 754bbaa1d..5300c93c8 100644 --- a/tests/paths.py +++ b/tests/paths.py @@ -2,4 +2,6 @@ TORCHJD_DIR = Path(__file__).parent.parent TESTS_DIR = Path(__file__).parent +PLOTS_RESULTS_DIR = TESTS_DIR / "plots" / "results" PROFILING_RESULTS_DIR = TESTS_DIR / "profiling" / "results" +TRAJECTORIES_RESULTS_DIR = TESTS_DIR / "trajectories" / "results" diff --git a/tests/plots/static_plotter.py b/tests/plots/static_plotter.py index 87c3abdbe..2fa8bf898 100644 --- a/tests/plots/static_plotter.py +++ b/tests/plots/static_plotter.py @@ -1,6 +1,5 @@ -from pathlib import Path - import torch +from paths import PLOTS_RESULTS_DIR from plotly import graph_objects as go from plots._utils import ( @@ -268,9 +267,8 @@ def main( ) fig.update_yaxes(range=[-0.1, 2.1], showgrid=False, zeroline=False, visible=False) - results_dir = Path(__file__).parent / "results" - results_dir.mkdir(exist_ok=True) - fig.write_image(results_dir / f"{filename}.pdf") + PLOTS_RESULTS_DIR.mkdir(exist_ok=True) + fig.write_image(PLOTS_RESULTS_DIR / f"{filename}.pdf") # Alternative: use .svg here and then convert to pdf using rsvg-convert. Install # [rsvg-convert](https://manpages.ubuntu.com/manpages/bionic/man1/rsvg-convert.1.html) and run: # `rsvg-convert -f pdf -o filename.pdf filename.svg` diff --git a/tests/trajectories/_paths.py b/tests/trajectories/_paths.py index e92f0514a..764feded2 100644 --- a/tests/trajectories/_paths.py +++ b/tests/trajectories/_paths.py @@ -1,23 +1,23 @@ from pathlib import Path -RESULTS_DIR = Path(__file__).parent / "results" +from tests.paths import TRAJECTORIES_RESULTS_DIR def get_params_dir(objective_key: str) -> Path: - return RESULTS_DIR / objective_key / "X" + return TRAJECTORIES_RESULTS_DIR / objective_key / "X" def get_values_dir(objective_key: str) -> Path: - return RESULTS_DIR / objective_key / "Y" + return TRAJECTORIES_RESULTS_DIR / objective_key / "Y" def get_param_plots_dir(objective_key: str) -> Path: - return RESULTS_DIR / objective_key / "param_plots" + return TRAJECTORIES_RESULTS_DIR / objective_key / "param_plots" def get_value_plots_dir(objective_key: str) -> Path: - return RESULTS_DIR / objective_key / "value_plots" + return TRAJECTORIES_RESULTS_DIR / objective_key / "value_plots" def get_distance_to_pf_plots_dir(objective_key: str) -> Path: - return RESULTS_DIR / objective_key / "distance_to_pf" + return TRAJECTORIES_RESULTS_DIR / objective_key / "distance_to_pf" diff --git a/tests/trajectories/optimize.py b/tests/trajectories/optimize.py index 9bd1b35cb..1e78b480c 100644 --- a/tests/trajectories/optimize.py +++ b/tests/trajectories/optimize.py @@ -18,6 +18,7 @@ import numpy as np import torch +from tests.paths import TRAJECTORIES_RESULTS_DIR from torchjd.aggregation import Stateful from trajectories._constants import ( AGGREGATORS, @@ -29,7 +30,7 @@ OBJECTIVES, ) from trajectories._optimization import optimize -from trajectories._paths import RESULTS_DIR, get_params_dir, get_values_dir +from trajectories._paths import get_params_dir, get_values_dir warnings.filterwarnings("ignore") @@ -88,7 +89,7 @@ def main() -> None: "learning_rates": learning_rates, "initial_points": initial_points, } - with open(RESULTS_DIR / objective_key / "metadata.json", "w") as f: + with open(TRAJECTORIES_RESULTS_DIR / objective_key / "metadata.json", "w") as f: json.dump(metadata, f) for aggregator_key in aggregator_keys: diff --git a/tests/trajectories/plot_distance_to_pf.py b/tests/trajectories/plot_distance_to_pf.py index de5074f0c..c8d0eee2c 100644 --- a/tests/trajectories/plot_distance_to_pf.py +++ b/tests/trajectories/plot_distance_to_pf.py @@ -15,9 +15,10 @@ import numpy as np import torch +from tests.paths import TRAJECTORIES_RESULTS_DIR from trajectories._constants import AGGREGATOR_ORDER, AGGREGATORS, LATEX_NAMES, OBJECTIVES from trajectories._pareto_utils import make_2d_pf_distance_fn -from trajectories._paths import RESULTS_DIR, get_distance_to_pf_plots_dir, get_values_dir +from trajectories._paths import get_distance_to_pf_plots_dir, get_values_dir from trajectories._plotters import ( MultiEvolutionPlotter, SquareBoxAspectSetter, @@ -51,7 +52,7 @@ def main() -> None: args = parser.parse_args() objective_key = args.objective - with open(RESULTS_DIR / objective_key / "metadata.json") as f: + with open(TRAJECTORIES_RESULTS_DIR / objective_key / "metadata.json") as f: metadata = json.load(f) values_dir = get_values_dir(objective_key) diff --git a/tests/trajectories/plot_params.py b/tests/trajectories/plot_params.py index d726eaa94..c58840358 100644 --- a/tests/trajectories/plot_params.py +++ b/tests/trajectories/plot_params.py @@ -14,6 +14,7 @@ import matplotlib.pyplot as plt import numpy as np +from tests.paths import TRAJECTORIES_RESULTS_DIR from trajectories._constants import ( AGGREGATOR_ORDER, AGGREGATORS, @@ -24,7 +25,7 @@ from trajectories._objectives import ElementWiseQuadratic, WithSPSMappingMixin from trajectories._optimization import compute_gradient_cosine_similarities from trajectories._pareto_utils import sample_2d_spss -from trajectories._paths import RESULTS_DIR, get_param_plots_dir, get_params_dir +from trajectories._paths import get_param_plots_dir, get_params_dir from trajectories._plotters import ( AxesPlotter, ContentLimAdjuster, @@ -61,7 +62,7 @@ def main() -> None: args = parser.parse_args() objective_key = args.objective - with open(RESULTS_DIR / objective_key / "metadata.json") as f: + with open(TRAJECTORIES_RESULTS_DIR / objective_key / "metadata.json") as f: metadata = json.load(f) params_dir = get_params_dir(objective_key) diff --git a/tests/trajectories/plot_values.py b/tests/trajectories/plot_values.py index 08c33968c..145aaf1cf 100644 --- a/tests/trajectories/plot_values.py +++ b/tests/trajectories/plot_values.py @@ -14,6 +14,7 @@ import matplotlib.pyplot as plt import numpy as np +from tests.paths import TRAJECTORIES_RESULTS_DIR from trajectories._constants import ( AGGREGATOR_ORDER, AGGREGATORS, @@ -23,7 +24,7 @@ ) from trajectories._objectives import WithSPSMappingMixin from trajectories._pareto_utils import compute_normalized_2d_pf_distances, sample_2d_pf -from trajectories._paths import RESULTS_DIR, get_value_plots_dir, get_values_dir +from trajectories._paths import get_value_plots_dir, get_values_dir from trajectories._plotters import ( ContentLimAdjuster, HeatmapPlotter, @@ -58,7 +59,7 @@ def main() -> None: args = parser.parse_args() objective_key = args.objective - with open(RESULTS_DIR / objective_key / "metadata.json") as f: + with open(TRAJECTORIES_RESULTS_DIR / objective_key / "metadata.json") as f: metadata = json.load(f) values_dir = get_values_dir(objective_key)