Skip to content

Commit 7ba7e8e

Browse files
authored
Migrated all examples to the use of the new client, server, and trainer APIs. (#396)
* Updated the clean script to traverse all subdirectories. * Sync context whenenver a client ID change is detected in the client. * Revised attack_adaptive, llm_split_learning, and the cleanup script. * ruff format & ruff check --fix. * Added tests for models, datasources, processors, and samplers. * IMproved tests (with 147 now). * Fixed import issues with Polaris and deprecation warnings in DLG. * Moved DLG documentation into docs/. * Improved MPC so that mpc_data is stored in 'runtime/'. * Reorganized tests. * Fixed runtime errors in Maskcrypt. * Fixed the basic and ssl trainer so that SSL example 'byol' runs. * Supports automatic data downloading with a context manager and a download guard; removed docs on the -d option. * Migrated Calibre to the use of server strategies. * Calibre now runs successfully to completion. * Fixed issues with three-layer FL algorithms. * Improved parallel downloading of the MNIST dataset. * Fixed issues running model search examples. * Fixed a sampler issue in differential privacy trainer; updated the docs to reflect the latest APIs. * Removed logging to files and migrated aggregation to using server strategies. * Released v1.4. * ruff check --fix & ruff format.
1 parent 2762c18 commit 7ba7e8e

File tree

69 files changed

+1327
-996
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1327
-996
lines changed

.gitignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,6 @@ uv.lock
164164

165165
# multi-party computation data
166166
mpc_data
167+
168+
# models
169+
**/*.pt

clean.py

Lines changed: 0 additions & 107 deletions
This file was deleted.

cleanup.py

Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
#!/usr/bin/env python3
2+
"""Clean temporary directories across the Plato codebase."""
3+
4+
from __future__ import annotations
5+
6+
import argparse
7+
import os
8+
import shutil
9+
from pathlib import Path
10+
from typing import Iterable
11+
12+
RUNTIME_NAME = "runtime"
13+
PYCACHE_NAME = "__pycache__"
14+
EXCLUDED_NAMES = {".venv"}
15+
16+
17+
def find_runtime_roots(root: Path) -> list[Path]:
18+
"""Return all ``runtime`` directories located beneath ``root``."""
19+
root = root.resolve()
20+
21+
runtime_roots: list[Path] = []
22+
seen_runtime: set[Path] = set()
23+
24+
def add_runtime(candidate: Path) -> None:
25+
try:
26+
resolved = candidate.resolve()
27+
except OSError:
28+
return
29+
if resolved in seen_runtime or not candidate.is_dir():
30+
return
31+
seen_runtime.add(resolved)
32+
runtime_roots.append(candidate)
33+
34+
if root.name == RUNTIME_NAME:
35+
add_runtime(root)
36+
37+
for current, dirnames, _ in os.walk(root, topdown=True):
38+
pruned_dirs = []
39+
for dirname in dirnames:
40+
if dirname in EXCLUDED_NAMES:
41+
continue
42+
if dirname == RUNTIME_NAME:
43+
add_runtime(Path(current) / dirname)
44+
continue
45+
if dirname == PYCACHE_NAME:
46+
continue
47+
pruned_dirs.append(dirname)
48+
dirnames[:] = pruned_dirs
49+
50+
return runtime_roots
51+
52+
53+
def iter_pycache_directories(root: Path) -> Iterable[Path]:
54+
"""Yield all ``__pycache__`` directories under ``root`` (excluding excluded paths)."""
55+
root = root.resolve()
56+
57+
if root.name == PYCACHE_NAME and root.is_dir():
58+
yield root
59+
60+
seen_pycache: set[Path] = set()
61+
for current, dirnames, _ in os.walk(root, topdown=True):
62+
pruned_dirs = []
63+
for dirname in dirnames:
64+
if dirname in EXCLUDED_NAMES:
65+
continue
66+
if dirname == PYCACHE_NAME:
67+
candidate = Path(current) / dirname
68+
resolved_candidate = candidate.resolve()
69+
if resolved_candidate in seen_pycache:
70+
continue
71+
seen_pycache.add(resolved_candidate)
72+
yield candidate
73+
continue
74+
pruned_dirs.append(dirname)
75+
dirnames[:] = pruned_dirs
76+
77+
78+
def clean_directory(path: Path) -> int:
79+
"""Remove all contents of the directory at ``path``. Returns items deleted."""
80+
removed = 0
81+
for child in path.iterdir():
82+
try:
83+
if child.is_symlink() or child.is_file():
84+
child.unlink()
85+
elif child.is_dir():
86+
shutil.rmtree(child)
87+
else:
88+
continue
89+
removed += 1
90+
except OSError as exc:
91+
print(f"Failed to remove {child}: {exc}")
92+
return removed
93+
94+
95+
def remove_directory(path: Path) -> bool:
96+
"""Remove the directory at ``path`` entirely. Returns ``True`` on success."""
97+
try:
98+
shutil.rmtree(path)
99+
return True
100+
except OSError as exc:
101+
print(f"Failed to remove {path}: {exc}")
102+
return False
103+
104+
105+
def resolve_root(path_str: str | None) -> Path:
106+
"""Resolve the repository root to clean under."""
107+
if path_str is None:
108+
return Path(__file__).resolve().parent
109+
return Path(path_str).resolve()
110+
111+
112+
def parse_args() -> argparse.Namespace:
113+
parser = argparse.ArgumentParser(
114+
description=(
115+
"Remove Plato runtime directories (and their contents) under the "
116+
"given root directory and delete any __pycache__ folders."
117+
)
118+
)
119+
parser.add_argument(
120+
"root",
121+
nargs="?",
122+
help="Optional root directory to scan (defaults to script location).",
123+
)
124+
return parser.parse_args()
125+
126+
127+
def main() -> None:
128+
args = parse_args()
129+
root = resolve_root(args.root)
130+
131+
if not root.is_dir():
132+
raise SystemExit(f"Root path is not a directory: {root}")
133+
134+
print(f"Cleaning temporary directories under: {root}")
135+
136+
runtime_roots = find_runtime_roots(root)
137+
runtime_total = len(runtime_roots)
138+
runtime_removed = 0
139+
fallback_dirs = 0
140+
fallback_items = 0
141+
142+
for runtime_dir in runtime_roots:
143+
if remove_directory(runtime_dir):
144+
print(f"Deleted runtime directory {runtime_dir}")
145+
runtime_removed += 1
146+
continue
147+
148+
cleared = clean_directory(runtime_dir)
149+
print(
150+
f"Failed to delete {runtime_dir}; cleared {cleared} items instead."
151+
)
152+
fallback_dirs += 1
153+
fallback_items += cleared
154+
155+
if runtime_total == 0:
156+
print("No runtime directories found.")
157+
else:
158+
print(
159+
f"Removed {runtime_removed} of {runtime_total} runtime directories."
160+
)
161+
if fallback_dirs:
162+
print(
163+
f"Cleared {fallback_items} items in "
164+
f"{fallback_dirs} undeleted runtime directories."
165+
)
166+
167+
if not root.exists():
168+
print("Root directory removed; skipped __pycache__ cleanup.")
169+
return
170+
171+
pycache_removed = 0
172+
pycache_total = 0
173+
for pycache_dir in iter_pycache_directories(root):
174+
if remove_directory(pycache_dir):
175+
print(f"Deleted __pycache__ directory {pycache_dir}")
176+
pycache_removed += 1
177+
pycache_total += 1
178+
179+
if pycache_total == 0:
180+
print("No __pycache__ directories found.")
181+
else:
182+
print(f"Removed {pycache_removed} of {pycache_total} __pycache__ directories.")
183+
184+
185+
if __name__ == "__main__":
186+
main()

0 commit comments

Comments
 (0)