File size: 3,310 Bytes
5338e3e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
"""Independent checker for full-scale Claims 1, 3, and 4."""

from __future__ import annotations

import json
import math
import sys
from pathlib import Path


def check(payload: dict) -> dict:
    failures: list[str] = []
    claim_status = {"1": True, "3": True, "4": True}
    if payload["sampling"]["count"] != 5000:
        failures.append("paper-scale sample count is not 5000")
        claim_status["1"] = False
        claim_status["3"] = False
        claim_status["4"] = False
    for record in payload["kernels"]:
        label = record["kernel"]
        iterations = record["iterations_to_mean_error_below_1e-3"]
        if not 5 <= iterations <= 10:
            failures.append(f"{label}: iteration count {iterations} outside 5-10")
            claim_status["3"] = False
        metrics = {
            item["normalization"]: item
            for item in record["normalizations"]
        }
        sinkhorn = metrics["sinkhorn"]
        if sinkhorn["mass_max_error"] > 2e-10:
            failures.append(f"{label}: Sinkhorn mass")
            claim_status["1"] = False
            claim_status["4"] = False
        if sinkhorn["self_adjoint_relative_error"] > 2e-12:
            failures.append(f"{label}: Sinkhorn self-adjointness")
            claim_status["1"] = False
            claim_status["4"] = False
        if not math.isfinite(record["minimum_log_operator_entry_lower_bound"]):
            failures.append(f"{label}: positivity lower bound")
            claim_status["1"] = False
            claim_status["4"] = False
        if record["top_eigenvalues"][-1] > 1.0 + 2e-9:
            failures.append(f"{label}: spectral upper bound")
            claim_status["1"] = False
            claim_status["4"] = False
        if record["landmark_minimum_eigenvalue"] < -2e-11:
            failures.append(f"{label}: landmark PSD")
            claim_status["1"] = False
            claim_status["4"] = False
        if metrics["row"]["mass_max_error"] > 2e-12:
            failures.append(f"{label}: row control unexpectedly loses mass")
            claim_status["4"] = False
        if metrics["row"]["self_adjoint_relative_error"] < 1e-3:
            failures.append(f"{label}: row control did not lose self-adjointness")
            claim_status["4"] = False
        if metrics["symmetric"]["self_adjoint_relative_error"] > 2e-12:
            failures.append(f"{label}: symmetric control loses self-adjointness")
            claim_status["4"] = False
        if metrics["symmetric"]["mass_max_error"] < 1e-3:
            failures.append(f"{label}: symmetric control did not lose mass")
            claim_status["4"] = False
    return {
        "verifier": "independent_armadillo",
        "claim_status": claim_status,
        "pass": not failures,
        "failures": failures,
    }


def main() -> int:
    if len(sys.argv) != 3:
        raise SystemExit("usage: check_armadillo.py INPUT_JSON OUTPUT_JSON")
    payload = json.loads(Path(sys.argv[1]).read_text(encoding="utf-8"))
    result = check(payload)
    Path(sys.argv[2]).write_text(
        json.dumps(result, indent=2) + "\n", encoding="utf-8"
    )
    print("ARMADILLO_INDEPENDENT_CHECKER=" + json.dumps(result, sort_keys=True))
    return 0 if result["pass"] else 1


if __name__ == "__main__":
    raise SystemExit(main())