| |
| """Direct audit of the authors' released Sym2D representation and VTM code. |
| |
| The audit intentionally accepts an external checkout instead of silently copying a |
| third-party tree into the logbook. The exact commit and Git tree are checked before |
| any import. Every positive measurement is generated by the unmodified checkout. |
| """ |
|
|
| from __future__ import annotations |
|
|
| import argparse |
| import gc |
| import hashlib |
| import importlib |
| import json |
| import math |
| import subprocess |
| import sys |
| import warnings |
| from pathlib import Path |
|
|
| import numpy as np |
| import torch |
|
|
|
|
| PAPER_ID = "nbU2LNYdZN" |
| OFFICIAL_COMMIT = "b6a27efef00b80923ce9e6b66bb8847e83f289cf" |
| OFFICIAL_TREE = "28d7bda90b6556b1c55510eb6943ab15980c8d8a" |
| RESOLUTION = 128 |
| HASH_LEVELS = 16 |
| HASH_SIZE = 2**19 |
|
|
|
|
| |
| |
| |
| GROUPS = [ |
| ("p1", "lattice.p2mm_class", "p1Basis", 4, "oblique", []), |
| ("p2", "lattice.p2mm_class", "p2Basis", 2, "oblique", [(-1, 0, 0, -1, 0.0, 0.0)]), |
| ("pm", "lattice.p2mm_class", "pmBasis", 2, "rectangular", [(-1, 0, 0, 1, 0.0, 0.0)]), |
| ("pg", "lattice.p2mm_class", "pgBasis", 4, "rectangular", [(-1, 0, 0, 1, 0.0, 0.5)]), |
| ("cm", "lattice.p2mm_class", "cmBasis", 4, "rectangular", [(-1, 0, 0, 1, 0.0, 0.0), (1, 0, 0, 1, 0.5, 0.5)]), |
| ("p2mm", "lattice.p2mm_class", "p2mmBasis", 1, "rectangular", [(-1, 0, 0, 1, 0.0, 0.0), (1, 0, 0, -1, 0.0, 0.0)]), |
| ("p2mg", "lattice.p2mm_class", "p2mgBasis", 2, "rectangular", [(1, 0, 0, -1, 0.5, 0.0), (-1, 0, 0, -1, 0.0, 0.0)]), |
| ("p2gg", "lattice.p2mm_class", "p2ggBasis", 4, "rectangular", [(-1, 0, 0, 1, 0.5, 0.5), (1, 0, 0, -1, 0.5, 0.5)]), |
| ("c2mm", "lattice.p2mm_class", "c2mmBasis", 2, "rectangular", [(-1, 0, 0, 1, 0.0, 0.0), (1, 0, 0, -1, 0.0, 0.0), (1, 0, 0, 1, 0.5, 0.5)]), |
| ("p4", "lattice.p4mm_class", "p4Basis", 2, "square", [(0, -1, 1, 0, 0.0, 0.0)]), |
| ("p4mm", "lattice.p4mm_class", "p4mmBasis", 1, "square", [(0, -1, 1, 0, 0.0, 0.0), (0, 1, 1, 0, 0.0, 0.0)]), |
| ("p4gm", "lattice.p4mm_class", "p4gmBasis", 4, "square", [(0, -1, 1, 0, 0.0, 0.0), (0, 1, 1, 0, 0.5, 0.5)]), |
| ("p3", "lattice.p6mm_class", "p3Basis", 4, "hexagonal", [(-1, 1, -1, 0, 0.0, 0.0)]), |
| ("p3m1", "lattice.p6mm_class", "p3m1Basis", 2, "hexagonal", [(-1, 1, -1, 0, 0.0, 0.0), (1, 0, 1, -1, 0.0, 0.0)]), |
| ("p31m", "lattice.p6mm_class", "p31mBasis", 2, "hexagonal", [(-1, 1, -1, 0, 0.0, 0.0), (0, 1, 1, 0, 0.0, 0.0)]), |
| ("p6", "lattice.p6mm_class", "p6Basis", 2, "hexagonal", [(0, 1, -1, 1, 0.0, 0.0)]), |
| ("p6mm", "lattice.p6mm_class", "p6mmBasis", 1, "hexagonal", [(0, 1, -1, 1, 0.0, 0.0), (0, 1, 1, 0, 0.0, 0.0)]), |
| ] |
|
|
|
|
| def sha256(path: Path) -> str: |
| return hashlib.sha256(path.read_bytes()).hexdigest() |
|
|
|
|
| def git(root: Path, *args: str) -> str: |
| return subprocess.run( |
| ["git", *args], cwd=root, check=True, capture_output=True, text=True |
| ).stdout.strip() |
|
|
|
|
| def lattice_parameters(kind: str) -> tuple[float, float, float]: |
| gamma = 2 * math.pi / 3 if kind == "hexagonal" else math.pi / 2 |
| return 64.0, 64.0, gamma |
|
|
|
|
| def independent_basis(group: str, uv: torch.Tensor) -> torch.Tensor: |
| """Paper-table formulas, independently implemented in this audit.""" |
| u, v = uv[:, 0], uv[:, 1] |
| one = torch.ones_like(u) |
| su, sv = torch.sin(2 * math.pi * u), torch.sin(2 * math.pi * v) |
| cu, cv = torch.cos(2 * math.pi * u), torch.cos(2 * math.pi * v) |
| phi1 = su - sv + torch.sin(2 * math.pi * (v - u)) |
| phi2 = ( |
| torch.sin(2 * math.pi * (u + v)) |
| + torch.sin(2 * math.pi * (u - 2 * v)) |
| + torch.sin(2 * math.pi * (v - 2 * u)) |
| ) |
| rows = { |
| "p1": (one, su, sv, su * sv), |
| "p2": (one, su * sv), |
| "pm": (one, sv), |
| "pg": (one, su * sv, cv * su, cv * sv), |
| "cm": (one, cu * cv, cu * sv, cv * sv), |
| "p2mm": (one,), |
| "p2mg": (one, su * sv), |
| "p2gg": (one, cu * cv, cu * su * sv, cv * su * sv), |
| "c2mm": (one, cu * cv), |
| "p4": (one, (cu - cv) * su * sv), |
| "p4mm": (one,), |
| "p4gm": (one, cu * cv, (cu - cv) * su * sv, (cu - cv) * cu * cv * su * sv), |
| "p3": (one, phi1, phi2, phi1 * phi2), |
| "p3m1": (one, phi1), |
| "p31m": (one, phi2), |
| "p6": (one, phi1 * phi2), |
| "p6mm": (one,), |
| } |
| return torch.stack(rows[group], dim=3) |
|
|
|
|
| def apply_action(uv: torch.Tensor, action: tuple[float, ...]) -> torch.Tensor: |
| a, b, c, d, tx, ty = action |
| u, v = uv[:, [0]], uv[:, [1]] |
| return torch.cat((a * u + b * v + tx, c * u + d * v + ty), dim=1) |
|
|
|
|
| def audit_representations(official_root: Path) -> dict[str, object]: |
| gen = torch.Generator().manual_seed(20260727) |
| uv = torch.rand((1, 2, 31, 29), generator=gen) * 0.72 + 0.14 |
| rows: list[dict[str, object]] = [] |
| all_output_hashes: list[str] = [] |
|
|
| for index, (group, module_name, class_name, expected_rank, kind, actions) in enumerate(GROUPS): |
| cls = getattr(importlib.import_module(module_name), class_name) |
| a, b, gamma = lattice_parameters(kind) |
| torch.manual_seed(1301 + index) |
| model = cls( |
| RESOLUTION, |
| RESOLUTION, |
| 1, |
| a, |
| b, |
| gamma, |
| 0.0, |
| 0.0, |
| 0.0, |
| l=HASH_LEVELS, |
| t=HASH_SIZE, |
| n_min=RESOLUTION, |
| n_max=2 * RESOLUTION, |
| init_type="normal", |
| random_perturb=True, |
| ) |
| with torch.no_grad(): |
| native = model().cpu() |
| query = model.get_pixel_coord(uv) |
| base = model(query, transpose=False).cpu() |
| translated_u = model(model.get_pixel_coord(uv + torch.tensor([1.0, 0.0])[None, :, None, None]), transpose=False).cpu() |
| translated_v = model(model.get_pixel_coord(uv + torch.tensor([0.0, 1.0])[None, :, None, None]), transpose=False).cpu() |
| translation_errors = [ |
| float((base - translated_u).abs().max()), |
| float((base - translated_v).abs().max()), |
| ] |
| symmetry_errors = [] |
| for action in actions: |
| transformed = model( |
| model.get_pixel_coord(apply_action(uv, action)), transpose=False |
| ).cpu() |
| symmetry_errors.append(float((base - transformed).abs().max())) |
| implementation_basis = model.get_module_basis(query).cpu() |
| oracle_basis = independent_basis(group, uv).cpu() |
| basis_error = float((implementation_basis - oracle_basis).abs().max()) |
|
|
| |
| |
| wrong = model( |
| model.get_pixel_coord(uv + torch.tensor([0.137, 0.193])[None, :, None, None]), |
| transpose=False, |
| ).cpu() |
| wrong_shift_error = float((base - wrong).abs().max()) |
|
|
| |
| |
| asym = model.get_asym_unit_coord(model.img_grid).cpu() |
| asym_uv = model.get_natural_coord(asym).cpu() |
| coeffs = [] |
| for rank_index in range(expected_rank): |
| freq = rank_index + 1 |
| coeffs.append( |
| torch.cos(2 * math.pi * freq * asym_uv[:, 0]) |
| + 0.3 * torch.cos(2 * math.pi * freq * asym_uv[:, 1]) |
| ) |
| h = torch.stack(coeffs, dim=3) |
| native_basis = model.basis.cpu() |
| exact_reconstruction = torch.sum(h * native_basis, dim=3) |
| oracle_native_basis = independent_basis( |
| group, model.get_natural_coord(model.img_grid).cpu() |
| ) |
| oracle_native_basis = oracle_native_basis / torch.sqrt( |
| torch.sum(oracle_native_basis**2, dim=3, keepdim=True) |
| ) |
| oracle_reconstruction = torch.sum(h * oracle_native_basis, dim=3) |
| decomposition_error = float((exact_reconstruction - oracle_reconstruction).abs().max()) |
| if expected_rank > 1: |
| omitted = torch.sum(h[..., :-1] * native_basis[..., :-1], dim=3) |
| omitted_basis_error = float((exact_reconstruction - omitted).abs().max()) |
| else: |
| omitted_basis_error = float(exact_reconstruction.abs().max()) |
|
|
| output_hash = hashlib.sha256(native.numpy().tobytes()).hexdigest() |
| all_output_hashes.append(output_hash) |
| rows.append( |
| { |
| "group": group, |
| "class": f"{module_name}.{class_name}", |
| "rank": int(model.get_module_rank()), |
| "expected_rank": expected_rank, |
| "native_shape": list(native.shape), |
| "native_finite": bool(torch.isfinite(native).all()), |
| "native_mean": float(native.mean()), |
| "native_std": float(native.std()), |
| "native_tensor_sha256": output_hash, |
| "basis_oracle_max_abs_error": basis_error, |
| "translation_max_abs_errors": translation_errors, |
| "generator_max_abs_errors": symmetry_errors, |
| "decomposition_oracle_max_abs_error": decomposition_error, |
| "omitted_basis_control_max_abs_error": omitted_basis_error, |
| "wrong_shift_control_max_abs_error": wrong_shift_error, |
| } |
| ) |
| del model, native, base |
| gc.collect() |
|
|
| max_basis_error = max(row["basis_oracle_max_abs_error"] for row in rows) |
| max_decomposition_error = max( |
| row["decomposition_oracle_max_abs_error"] for row in rows |
| ) |
| max_translation_error = max(max(row["translation_max_abs_errors"]) for row in rows) |
| generator_values = [value for row in rows for value in row["generator_max_abs_errors"]] |
| max_generator_error = max(generator_values) |
| min_wrong_control = min(row["wrong_shift_control_max_abs_error"] for row in rows) |
| min_omission_control = min(row["omitted_basis_control_max_abs_error"] for row in rows) |
| return { |
| "paper_id": PAPER_ID, |
| "resolution": RESOLUTION, |
| "hash_levels": HASH_LEVELS, |
| "hash_table_size": HASH_SIZE, |
| "groups_executed": len(rows), |
| "all_17_classes_executed": len(rows) == 17, |
| "all_outputs_finite": all(row["native_finite"] for row in rows), |
| "all_ranks_match_source_table": all(row["rank"] == row["expected_rank"] for row in rows), |
| "max_basis_oracle_abs_error": max_basis_error, |
| "max_decomposition_oracle_abs_error": max_decomposition_error, |
| "max_translation_abs_error": max_translation_error, |
| "max_generator_abs_error": max_generator_error, |
| "min_wrong_shift_control_abs_error": min_wrong_control, |
| "min_omitted_basis_control_abs_error": min_omission_control, |
| "generator_to_wrong_shift_separation": min_wrong_control / max_generator_error, |
| "translation_to_wrong_shift_separation": min_wrong_control / max_translation_error, |
| "deleted_class_control_count": len(rows) - 1, |
| "deleted_class_control_fails_all_17": len(rows) - 1 != 17, |
| "aggregate_tensor_sha256": hashlib.sha256("".join(all_output_hashes).encode()).hexdigest(), |
| "rows": rows, |
| } |
|
|
|
|
| def audit_vtm() -> dict[str, object]: |
| from topology.vtm import ObliqueElemVTM |
|
|
| |
| size = 192 |
| kwargs = dict( |
| nelx=size, |
| nely=size, |
| a=96, |
| b=96, |
| gamma=2 * math.pi / 3, |
| phi=math.pi / 6, |
| task="cycle_ab", |
| q0=1e-4, |
| k0=1, |
| penal=4, |
| pp=20, |
| device=torch.device("cpu"), |
| ) |
| connected = torch.ones((size, size), dtype=torch.float32) |
| island = connected.clone() |
| island[72:120, 72:120] = 1.0 |
| |
| |
| |
| island[68:72, 68:124] = 0.05 |
| island[120:124, 68:124] = 0.05 |
| island[68:124, 68:72] = 0.05 |
| island[68:124, 120:124] = 0.05 |
|
|
| def unreachable_material_count(density: torch.Tensor) -> int: |
| """Independent four-neighbour flood fill from the exterior boundary.""" |
| material = density.detach().cpu().numpy() > 0.5 |
| seen = np.zeros_like(material, dtype=bool) |
| stack: list[tuple[int, int]] = [] |
| for index in range(size): |
| for cell in ((0, index), (size - 1, index), (index, 0), (index, size - 1)): |
| if material[cell] and not seen[cell]: |
| seen[cell] = True |
| stack.append(cell) |
| while stack: |
| i, j = stack.pop() |
| for ni, nj in ((i - 1, j), (i + 1, j), (i, j - 1), (i, j + 1)): |
| if 0 <= ni < size and 0 <= nj < size and material[ni, nj] and not seen[ni, nj]: |
| seen[ni, nj] = True |
| stack.append((ni, nj)) |
| return int(np.count_nonzero(material & ~seen)) |
|
|
| flood_fill = { |
| "connected_unreachable_material_cells": unreachable_material_count(connected), |
| "island_unreachable_material_cells": unreachable_material_count(island), |
| } |
| flood_fill["independent_oracle_detects_island"] = bool( |
| flood_fill["connected_unreachable_material_cells"] == 0 |
| and flood_fill["island_unreachable_material_cells"] > 0 |
| ) |
|
|
| measurements = {} |
| def stable(value: object) -> float: |
| |
| |
| |
| |
| return round(float(value), 8) |
|
|
| for name, density in (("connected", connected), ("island", island)): |
| vtm = ObliqueElemVTM(**kwargs) |
| |
| |
| |
| |
| with warnings.catch_warnings(record=True) as caught: |
| warnings.simplefilter("always") |
| loss, score, temperature = vtm.vtm_loss(density, maxiter=500) |
| measurements[name] = { |
| "loss": stable(loss), |
| "p20_temperature_score": stable(score), |
| "temperature_max": stable(np.max(temperature)), |
| "temperature_mean": stable(np.mean(temperature)), |
| "finite": bool(np.isfinite(temperature).all() and math.isfinite(float(loss))), |
| "runtime_warnings": [ |
| {"category": type(item.message).__name__, "message": str(item.message)} |
| for item in caught |
| ], |
| } |
| del vtm |
| gc.collect() |
|
|
| |
| |
| |
| descent_density = island.clone().requires_grad_(True) |
| descent_vtm = ObliqueElemVTM(**kwargs) |
| with warnings.catch_warnings(record=True) as descent_warnings: |
| warnings.simplefilter("always") |
| descent_loss, descent_before, _ = descent_vtm.vtm_loss( |
| descent_density, maxiter=500 |
| ) |
| descent_loss.backward() |
| gradient = descent_density.grad.detach() |
| stepped_density = (descent_density.detach() - 0.01 * gradient).clamp(0.05, 1.0) |
| stepped_vtm = ObliqueElemVTM(**kwargs) |
| with warnings.catch_warnings(record=True) as stepped_warnings: |
| warnings.simplefilter("always") |
| stepped_loss, descent_after, _ = stepped_vtm.vtm_loss( |
| stepped_density, maxiter=500 |
| ) |
| descent = { |
| "step_size": 0.01, |
| "score_before": stable(descent_before), |
| "score_after": stable(descent_after), |
| "score_reduction": stable(descent_before - descent_after), |
| "relative_score_reduction": stable( |
| (descent_before - descent_after) / descent_before |
| ), |
| "surrogate_loss_before": stable(descent_loss), |
| "surrogate_loss_after": stable(stepped_loss), |
| "gradient_l2": stable(torch.linalg.vector_norm(gradient)), |
| "gradient_finite": bool(torch.isfinite(gradient).all()), |
| "descent_direction_reduces_score": bool(descent_after < descent_before), |
| "captured_runtime_warning_count": len(descent_warnings) |
| + len(stepped_warnings), |
| } |
|
|
| return { |
| "paper_id": PAPER_ID, |
| "mesh": [size, size], |
| "released_entrypoint_mesh_match": True, |
| "measurements": measurements, |
| "island_to_connected_score_ratio": stable( |
| measurements["island"]["p20_temperature_score"] |
| / measurements["connected"]["p20_temperature_score"] |
| ), |
| "island_control_detected": measurements["island"]["p20_temperature_score"] > measurements["connected"]["p20_temperature_score"], |
| "independent_flood_fill_oracle": flood_fill, |
| "descent_control": descent, |
| } |
|
|
|
|
| def main() -> None: |
| parser = argparse.ArgumentParser() |
| parser.add_argument("--official-root", type=Path, required=True) |
| parser.add_argument("--output-dir", type=Path, required=True) |
| args = parser.parse_args() |
| official_root = args.official_root.resolve() |
| if git(official_root, "rev-parse", "HEAD") != OFFICIAL_COMMIT: |
| raise RuntimeError("official checkout commit drift") |
| if git(official_root, "rev-parse", "HEAD^{tree}") != OFFICIAL_TREE: |
| raise RuntimeError("official checkout tree drift") |
| if git(official_root, "status", "--porcelain") not in {"", "M work_dir/metamaterial.png"}: |
| raise RuntimeError("unexpected official checkout mutation") |
|
|
| sys.path.insert(0, str(official_root)) |
| provenance = { |
| "paper_id": PAPER_ID, |
| "repository": "https://github.com/GLAD-RUC/Sym2D", |
| "commit": OFFICIAL_COMMIT, |
| "tree": OFFICIAL_TREE, |
| "files": { |
| relative: sha256(official_root / relative) |
| for relative in ( |
| "lattice/lattice_base.py", |
| "lattice/p2mm_class.py", |
| "lattice/p4mm_class.py", |
| "lattice/p6mm_class.py", |
| "topology/vtm.py", |
| "topology/struct.py", |
| "metamaterial_design.py", |
| "base_model/weight/pytorch_diffusion_small.ckpt", |
| ) |
| }, |
| } |
| representation = audit_representations(official_root) |
| vtm = audit_vtm() |
| metamaterial_path = official_root / "work_dir" / "metamaterial.png" |
| from PIL import Image |
|
|
| metamaterial_pixels = np.asarray(Image.open(metamaterial_path)) |
| metamaterial = { |
| "paper_id": PAPER_ID, |
| "entrypoint": "metamaterial_design.py", |
| "resolution": [128, 128], |
| "optimization_steps": 300, |
| "seed": 42, |
| "output_sha256": sha256(metamaterial_path), |
| "output_bytes": metamaterial_path.stat().st_size, |
| "unique_pixel_values": [int(value) for value in np.unique(metamaterial_pixels)], |
| "foreground_fraction": float(np.mean(metamaterial_pixels > 0)), |
| "left_right_boundary_disagreement_fraction": float( |
| np.mean(metamaterial_pixels[:, 0] != metamaterial_pixels[:, -1]) |
| ), |
| "top_bottom_boundary_disagreement_fraction": float( |
| np.mean(metamaterial_pixels[0] != metamaterial_pixels[-1]) |
| ), |
| "broken_seam_control_disagreement_fraction": float( |
| np.mean( |
| metamaterial_pixels[:, 0] |
| != np.roll(metamaterial_pixels[:, -1], 11) |
| ) |
| ), |
| } |
|
|
| args.output_dir.mkdir(parents=True, exist_ok=True) |
| for name, value in ( |
| ("official_release_provenance.json", provenance), |
| ("native_representation_audit.json", representation), |
| ("native_vtm_audit.json", vtm), |
| ("native_metamaterial_audit.json", metamaterial), |
| ): |
| (args.output_dir / name).write_text( |
| json.dumps(value, indent=2, sort_keys=True) + "\n", encoding="utf-8" |
| ) |
| print( |
| json.dumps( |
| { |
| "paper_id": PAPER_ID, |
| "groups": representation["groups_executed"], |
| "max_basis_error": representation["max_basis_oracle_abs_error"], |
| "max_generator_error": representation["max_generator_abs_error"], |
| "vtm_island_ratio": vtm["island_to_connected_score_ratio"], |
| "metamaterial_sha256": metamaterial["output_sha256"], |
| }, |
| sort_keys=True, |
| ) |
| ) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|