wave9 complete: 458/207 — airflow/argo/pytorch-0003/tf/jax/pyg/grpc/thrift + graphhopper/valhalla

This commit is contained in:
russell@unturf.com 2026-03-27 16:59:04 -04:00
parent 81bc62b9cb
commit ab10b2f555
22 changed files with 2889 additions and 16 deletions

View file

@ -0,0 +1,262 @@
package unit;
import java.util.*;
/**
* pytorch-geometric-0001: smiles.py list.index() O(L×A) → O(A) with dict
*
* Simulates the defective pattern from torch_geometric/utils/smiles.py:
* from_rdmol() calls x_map[key].index(value) for each atom feature,
* where x_map[key] is a List. This is O(L) per call, called A×9 times
* per molecule, M molecules total → O(M × A × L).
*
* Fixed: pre-build x_idx[key] = {value → index} HashMap → O(1) lookup.
*
* Run: javac -d . PyGSmilesIndexAlgorithm.java && java unit.PyGSmilesIndexAlgorithm
*/
public class PyGSmilesIndexAlgorithm {
// ---- Result ----
static class Result {
final int slowOps;
final int fastOps;
Result(int slowOps, int fastOps) {
this.slowOps = slowOps;
this.fastOps = fastOps;
}
}
// ---- Defective: list.index() O(L) per lookup ----
static class DefectiveMolProcessor {
// Simulates x_map['atomic_num'] = list(range(0, 119))
final List<Integer> atomicNumList;
// Simulates x_map['chirality'] = 9 entries
final List<String> chiralityList;
// Simulates e_map['bond_type'] = 22 entries
final List<String> bondTypeList;
int opCount = 0;
DefectiveMolProcessor() {
atomicNumList = new ArrayList<>();
for (int i = 0; i < 119; i++) atomicNumList.add(i);
chiralityList = new ArrayList<>();
String[] chiralities = {"CHI_UNSPECIFIED","CHI_TETRAHEDRAL_CW","CHI_TETRAHEDRAL_CCW",
"CHI_OTHER","CHI_TETRAHEDRAL","CHI_ALLENE","CHI_SQUAREPLANAR",
"CHI_TRIGONALBIPYRAMIDAL","CHI_OCTAHEDRAL"};
chiralityList.addAll(Arrays.asList(chiralities));
bondTypeList = new ArrayList<>();
for (int i = 0; i < 22; i++) bondTypeList.add("BOND_TYPE_" + i);
}
// O(L) list scan — mirrors list.index()
int listIndex(List<?> list, Object value) {
for (int i = 0; i < list.size(); i++) {
opCount++;
if (list.get(i).equals(value)) return i;
}
throw new NoSuchElementException("Value not found: " + value);
}
// Process one molecule: A atoms, B bonds
// Each atom: 3 list.index() calls (atomic_num, chirality, dummy)
// Each bond: 1 list.index() call (bond_type)
void processMolecule(int[] atomNums, String[] chiralTags, String[] bondTypes) {
for (int i = 0; i < atomNums.length; i++) {
listIndex(atomicNumList, atomNums[i]);
listIndex(chiralityList, chiralTags[i % chiralTags.length]);
// Simulate remaining 7 atom feature lookups (simplified):
// degree, formal_charge, num_hs, num_radical, hybridization,
// is_aromatic, is_in_ring — all small lists, count as 7 ops each
opCount += 7;
}
for (String bt : bondTypes) {
listIndex(bondTypeList, bt);
}
}
Result run(int[][] atomNumsPerMol, String[] chiralTags, String[] bondTypes) {
opCount = 0;
for (int[] atomNums : atomNumsPerMol) {
processMolecule(atomNums, chiralTags, bondTypes);
}
return new Result(opCount, -1);
}
}
// ---- Fixed: HashMap O(1) lookup ----
static class FixedMolProcessor {
final Map<Integer, Integer> atomicNumIdx;
final Map<String, Integer> chiralityIdx;
final Map<String, Integer> bondTypeIdx;
int opCount = 0;
FixedMolProcessor() {
// Build index maps once at module load
atomicNumIdx = new HashMap<>();
for (int i = 0; i < 119; i++) atomicNumIdx.put(i, i);
chiralityIdx = new HashMap<>();
String[] chiralities = {"CHI_UNSPECIFIED","CHI_TETRAHEDRAL_CW","CHI_TETRAHEDRAL_CCW",
"CHI_OTHER","CHI_TETRAHEDRAL","CHI_ALLENE","CHI_SQUAREPLANAR",
"CHI_TRIGONALBIPYRAMIDAL","CHI_OCTAHEDRAL"};
for (int i = 0; i < chiralities.length; i++) chiralityIdx.put(chiralities[i], i);
bondTypeIdx = new HashMap<>();
for (int i = 0; i < 22; i++) bondTypeIdx.put("BOND_TYPE_" + i, i);
}
int mapGet(Map<?, Integer> map, Object key) {
opCount++; // one op per lookup (hash + compare)
return map.get(key);
}
void processMolecule(int[] atomNums, String[] chiralTags, String[] bondTypes) {
for (int i = 0; i < atomNums.length; i++) {
mapGet(atomicNumIdx, atomNums[i]);
mapGet(chiralityIdx, chiralTags[i % chiralTags.length]);
opCount += 7; // 7 other O(1) dict lookups
}
for (String bt : bondTypes) {
mapGet(bondTypeIdx, bt);
}
}
Result run(int[][] atomNumsPerMol, String[] chiralTags, String[] bondTypes) {
opCount = 0;
for (int[] atomNums : atomNumsPerMol) {
processMolecule(atomNums, chiralTags, bondTypes);
}
return new Result(-1, opCount);
}
}
// ---- check helper ----
static int passed = 0;
static int total = 0;
static void check(String name, boolean condition) {
total++;
if (condition) {
passed++;
System.out.println(" PASS: " + name);
} else {
System.out.println(" FAIL: " + name);
}
}
public static void main(String[] args) {
System.out.println("pytorch-geometric-0001: smiles.py list.index() O(L*A) -> O(A)");
System.out.println();
// Build test data: simulate molecules with varying atom counts
// Atoms use atomic nums spread across the list to trigger long scans
String[] chiralTags = {"CHI_UNSPECIFIED", "CHI_TETRAHEDRAL_CW", "CHI_OTHER"};
String[] bondTypes = {"BOND_TYPE_0", "BOND_TYPE_10", "BOND_TYPE_21"};
// ---- Test 1: Small molecule (10 atoms, 9 bonds) ----
{
int M = 1;
int[][] atomNums = new int[M][];
// Use high atomic numbers to stress the list scan
atomNums[0] = new int[]{100, 110, 90, 50, 118, 60, 80, 30, 5, 1};
DefectiveMolProcessor slow = new DefectiveMolProcessor();
Result slowR = slow.run(atomNums, chiralTags, bondTypes);
FixedMolProcessor fast = new FixedMolProcessor();
Result fastR = fast.run(atomNums, chiralTags, bondTypes);
System.out.println("Test 1: 1 molecule, 10 atoms");
System.out.println(" Slow ops: " + slowR.slowOps);
System.out.println(" Fast ops: " + fastR.fastOps);
check("slow > fast (list scan > dict lookup)", slowR.slowOps > fastR.fastOps);
check("slow ops > 300 (O(L) scans dominate)", slowR.slowOps > 300);
}
// ---- Test 2: Large dataset (1000 molecules, 18 atoms each) ----
{
int M = 1000;
int A = 18;
int[][] atomNums = new int[M][A];
Random rng = new Random(42);
for (int m = 0; m < M; m++) {
for (int a = 0; a < A; a++) {
atomNums[m][a] = rng.nextInt(119);
}
}
DefectiveMolProcessor slow = new DefectiveMolProcessor();
Result slowR = slow.run(atomNums, chiralTags, bondTypes);
FixedMolProcessor fast = new FixedMolProcessor();
Result fastR = fast.run(atomNums, chiralTags, bondTypes);
System.out.println("Test 2: 1000 molecules, 18 atoms each");
System.out.println(" Slow ops: " + slowR.slowOps);
System.out.println(" Fast ops: " + fastR.fastOps);
double ratio = (double) slowR.slowOps / fastR.fastOps;
System.out.printf(" Ratio slow/fast: %.1fx%n", ratio);
check("slow > 5x fast ops (O(L) overhead confirmed)", ratio > 5.0);
check("slow ops scale with L=119 (>500k for M=1000,A=18)", slowR.slowOps > 500_000);
}
// ---- Test 3: Correctness — same results ----
{
int[][] singleMol = {{6, 7, 8, 1, 16}}; // C, N, O, H, S
DefectiveMolProcessor slow = new DefectiveMolProcessor();
FixedMolProcessor fast = new FixedMolProcessor();
// Verify same index returned for known values
int slowIdx = slow.listIndex(slow.atomicNumList, 6); // Carbon = index 6
int fastIdx = fast.atomicNumIdx.get(6); // Carbon = index 6
System.out.println("Test 3: correctness check for atomic_num=6 (Carbon)");
System.out.println(" Slow index: " + slowIdx + ", Fast index: " + fastIdx);
check("slow and fast return same index (6)", slowIdx == fastIdx && fastIdx == 6);
int slowChiral = slow.listIndex(slow.chiralityList, "CHI_TETRAHEDRAL_CW");
int fastChiral = fast.chiralityIdx.get("CHI_TETRAHEDRAL_CW");
System.out.println("Test 4: correctness check for chirality=CHI_TETRAHEDRAL_CW");
check("slow and fast return same chirality index (1)", slowChiral == fastChiral && fastChiral == 1);
}
// ---- Test 4: O(n^2) scaling — double molecule count doubles slow more ----
{
int A = 10;
String[] chiralTagsT = {"CHI_UNSPECIFIED"};
String[] bondTypesT = {"BOND_TYPE_21"}; // index 21 = worst case scan
int M1 = 100;
int M2 = 200;
int[][] atomNums1 = new int[M1][A];
int[][] atomNums2 = new int[M2][A];
for (int m = 0; m < M2; m++) {
for (int a = 0; a < A; a++) {
int v = 100 + (m % 19); // high atomic nums to stress scan
if (m < M1) atomNums1[m][a] = v;
atomNums2[m][a] = v;
}
}
DefectiveMolProcessor slow1 = new DefectiveMolProcessor();
DefectiveMolProcessor slow2 = new DefectiveMolProcessor();
slow1.run(atomNums1, chiralTagsT, bondTypesT);
slow2.run(atomNums2, chiralTagsT, bondTypesT);
System.out.println("Test 5: O(n) scaling — 2x molecules → ~2x ops");
System.out.println(" M=" + M1 + " ops: " + slow1.opCount);
System.out.println(" M=" + M2 + " ops: " + slow2.opCount);
double scalingRatio = (double) slow2.opCount / slow1.opCount;
System.out.printf(" Scaling: %.2fx (should be ~2.0)%n", scalingRatio);
check("slow ops scale ~2x when molecules doubled", scalingRatio > 1.9 && scalingRatio < 2.1);
}
System.out.println();
System.out.println(passed + "/" + total + " PASS");
}
}