summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/main.py11
-rw-r--r--src/runner.py26
2 files changed, 29 insertions, 8 deletions
diff --git a/src/main.py b/src/main.py
index 36297bc..e96ee33 100644
--- a/src/main.py
+++ b/src/main.py
@@ -2,6 +2,7 @@
Main entry point for running experiments.
Uses config.yaml to define what to run.
"""
+import argparse
from runner import run_from_config
from logger import setup_logger
from config_loader import ConfigLoader
@@ -9,8 +10,14 @@ from config_loader import ConfigLoader
def main():
"""Run all experiments defined in config.yaml."""
+ parser = argparse.ArgumentParser(description="Run experiments from config")
+ parser.add_argument("--config", default="config.yaml", help="Path to config file")
+ parser.add_argument("--no-resume", dest="resume", action="store_false",
+ default=True, help="Ignore existing logs and start fresh")
+ args = parser.parse_args()
+
# Load config to get logging settings
- config = ConfigLoader("config.yaml")
+ config = ConfigLoader(args.config)
config.load()
# Initialize logger
@@ -23,7 +30,7 @@ def main():
log_file=log_config.get('file')
)
- run_from_config("config.yaml")
+ run_from_config(args.config, resume=args.resume)
if __name__ == "__main__":
diff --git a/src/runner.py b/src/runner.py
index 3326df0..d81e3cf 100644
--- a/src/runner.py
+++ b/src/runner.py
@@ -63,17 +63,31 @@ class ExperimentRunner:
else:
# Parallel execution
logger.info(f"Running with {max_workers} parallel workers")
+ from tqdm import tqdm
+ from tqdm.contrib.logging import logging_redirect_tqdm
+ import logging
+
+ # Reduce console spam during parallel runs to keep the progress bar clean
+ for handler in logger.handlers:
+ if isinstance(handler, logging.StreamHandler) and not isinstance(handler, logging.FileHandler):
+ # Keep console relatively quiet (WARNING/ERROR/CRITICAL)
+ handler.setLevel(logging.WARNING)
+
with concurrent.futures.ThreadPoolExecutor(max_workers=max_workers) as executor:
futures = {
executor.submit(self._execute_work_item, item): item
for item in work_items
}
- for future in concurrent.futures.as_completed(futures):
- item = futures[future]
- try:
- future.result()
- except Exception as e:
- logger.critical(f"Work item failed: {item.get('label', 'unknown')}: {e}")
+ with logging_redirect_tqdm():
+ with tqdm(total=total_items, desc="Running Experiments", unit="run", dynamic_ncols=True) as pbar:
+ for future in concurrent.futures.as_completed(futures):
+ item = futures[future]
+ try:
+ future.result()
+ except Exception as e:
+ logger.critical(f"Work item failed: {item.get('label', 'unknown')}: {e}")
+ pbar.write(f"ERROR: {item.get('label', 'unknown')} failed: {e}")
+ pbar.update(1)
# Summary
successful = sum(1 for r in self.results if r.get("success", False))