← gpu-pilot · json · source: CONTINUE_6_15_2026.md

▶ CONTINUE 6/15 (drive speedup + P&R-NEC + OTP)

Newest handoff: drive ~10x faster (res-8), drive serialization fix (res-8 output), P&R multi-seed routes via NEC, OTP-NE oracle + 19-pair validation. Two ⭐ TODOs queued. · updated 2026-06-15 06:50

TL;DR

  • Drive FIXED end-to-end: engine ~23s→~2s (res-8 OSRM coarsening) + res-8 OUTPUT for drive-containing requests (engine._collapse_to_res8) so the adapter builds ~15K not 107K features — public drive 500@121s → 200@~21s. No-modes byte-identical.
  • P&R multi-station seeding (K=4 nearest railheads, engine._access_rail_seeds): Piscataway P&R now rides the NEC (New Brunswick/Edison ~70min) instead of nearest Dunellen Raritan Valley (~83). Validated vs OTP-NE oracle (geocoder:8091, OTP 2.6.0). World Cup ruled out (NEC identical across dates).
  • ⭐ DO NEXT (user-prioritized): (1) <5s ADAPTER OPTIMIZATION — cache the static H3 cell→boundary ring + orjson in multimodal-adapter (the ~1ms/cell build is the remaining latency floor: drive ~21s, walk/transit ~15s). (2) ROBUST HOVER FIX — monkey-patch map.queryRenderedFeatures (onLoad) to filter missing layers; the deployed hasHex gate is only partial.
  • GOTCHAS: purge stale res-9 drive caches on engine deploy (cache-first serves old 107K payloads); NEVER put proxy_read_timeout in the shared nginx snippet (mapnjt.conf duplicate); res-9 GeoJSON iso ~20MB EXCEEDS Mongo 16MB doc cap — store COMPACT not GeoJSON; precompute = lazy Mongo cache + warm head, NOT the full PB-scale cross-product.

CONTINUE — 2026-06-15 — MultiModal drive speedup + P&R-NEC + OTP validation

Host: geocoder (RTX 5080, 172.26.1.95) · GPU engine hexmap-api :8098 (systemd) Live: https://multimodal.certihomes.com (geo2 .151; FE pm2 tlccommute :3000, adapter pm2 multimodal-adapter :5055) Repo: tlcengine/gpu-pilot @ 9346808 (pushed). Read first: memory multimodal-fuel-drive-shipped.md, hexmap-api-interactive.md, then this.

⭐ DO THESE NEXT (user-prioritized, 2026-06-15)

1. <5s ADAPTER OPTIMIZATION (boundary cache + orjson)

The remaining latency floor. Engine is now ~2s, but the adapter builds ~14–15K hex Features at ~1 ms/cell (~15–18s) — so drive ≈ 21s, walk/transit ≈ 15s. Fix in /DataDrive/krish/krish/multimodal-adapter/adapter.py (geo2): - Cache the static H3 cell→boundary ringh3.cell_to_boundary is called per cell every request (adapter.py _ring, ~line 346; loop ~line 454). The grid is fixed, so memoize in a module-level dict (lazy, or warm res-8+res-9 at startup) → per-request build becomes dict lookups, not h3 calls. - Use orjson for the response dump (pip install orjson in the adapter venv /home/krish/anaconda3; Flask Response(orjson.dumps(obj), mimetype=...)). - Target: any mode <~5s. pm2 restart multimodal-adapter. Mirror final adapter.py to gpu-pilot/multimodal/adapter-src/adapter.py.

2. ROBUST HOVER FIX (kill the hisochrone-fill console error for good)

Deployed Map.js has only the partial hasHex gate (Map.js:659) — it does NOT cover the post-paint race, so Error: layer 'hisochrone-fill' does not exist … queryRenderedFeatures can still flash on hover (react-map-gl@6 × maplibre@3 THROWS on a missing layer). Bulletproof fix in /DataDrive/krish/krish/front-end/components/Map.js: - Add a ref to <ReactMapGL> (~line 694; no ref/onLoad today) + an onLoad that grabs mapRef.current.getMap() and monkey-patches map.queryRenderedFeatures to filter options.layers to those that exist (map.getLayer(id)) and wrap in try/catch → return []. Then hover never throws regardless of layer lifecycle. - yarn build + pm2 restart tlccommute. Mirror to gpu-pilot/multimodal/fe-patches/Map.js. - NOTE: users may be on a cached bundle — hard-refresh to pick up index-*.js.

DONE this session (2026-06-14 → 15) — all committed + live

  • Drive engine ~10× faster (modes.osrm_table_dest_to_cells_coarse, OSRM_DRIVE_RES=8): OSRM-table the ~15K res-8 PARENTS of candidate cells, fan time+distance_m to res-9. compute_ms ~23000 → ~2000. (engine.py/modes.py)
  • Drive serialization fix (engine._collapse_to_res8, engine.py ~606/1139): any request containing a drive-family mode (drive/uber/pnr/knr) returns res-8 (~15K cells) not res-9 (~107K) → adapter no longer 500s. Public drive 500@121s → 200@~21s. out_res in response. Pure-transit stays res-9. No-modes byte-identical (core-hash cc034548… unchanged).
  • P&R multi-station seeding (engine._access_rail_seeds, modes.PNR_N_STATIONS=4): seeds K=4 nearest railheads/cell (was single nearest) → multi-source RAPTOR picks the fastest LINE. Piscataway P&R now rides NEC (New Brunswick/Edison ~70 min), not nearest Dunellen Raritan Valley (~83). Validated vs OTP.
  • Timeout chain (geo2, NOT in repo): adapter UPSTREAM_TIMEOUT 30→120, gunicorn workers 4→2, nginx proxy_read_timeout 130s on multimodal /click+/geocode.
  • OTP-NE oracle stood up on geocoder:8091 (java -Xmx24g -jar otp.jar --load /home/krish/otp-northeast --port 8091; OTP 2.6.0, graph.obj 2.6G, LegacyRestApi). Still running (pid was 1894099, 24G). 19-pair GPU-vs-OTP validation (multimodal/validate_otp.py): 11/19 within ±5 min; subway/LIRR/MNR/PATH/NEC-local all match; failures = no-Amtrak + transfer-choice + cross-date feed builds.
  • World Cup ruled out: NEC (Edison→Penn) identical 70 min/5 opts every date Jun 9 → Jul 22. Earlier "NEC broken" was the OLD/down OTP, not this fresh graph.

OTHER PENDING (after the two ⭐ above)

  • Lazy Mongo isochrone cache (the durable latency fix): compute-on-first-click → store COMPACT {cell_id→time,cost,dist} (NOT GeoJSON; render geometry from static H3 grid on read; ~150 KB/res-8 doc) → instant on repeat. Warm top-N commute dests overnight. Evolve the existing hexmap-api/cache/*.json + hexmap-tiles/. Matches commute.tlcengine.com (multimodal/api-ref/ Mongo+GeoJSON pattern). Do NOT brute-force the full cross-product (PB-scale; full precompute is days b/c drive/OSRM).
  • GPU cuGraph SSSP drive (sub-second): walk/bike already use cugraph_sssp; drive is the lone OSRM holdout. Needs a car-weighted tri-state OSM graph. May be MOOT if the adapter opt gets cold drive to ~5s.
  • Expand OTP validation (more pairs; dig the Amtrak / optimistic-transfer clusters).
  • National network toggles (Phase 2, multimodal/RECON.md).
  • FE/adapter repo homes: geo2 FE remote = third-party Bitbucket (branch routes); adapter has no remote → mirror to gpu-pilot (current durable path).

GOTCHAS (don't relearn)

  • Stale res-9 drive caches must be PURGED on engine deploy — the cache-first short-circuit serves old 107K payloads and the new res-8 path never runs. Clear hexmap-api/cache/iso_* drive-family entries + the geo2 adapter cache after engine changes.
  • sudo pw file = /home/krish/secert.txt (the typo'd name). Works for geo2 sudo too.
  • nginx: NEVER add proxy_read_timeout to the shared snippet /etc/nginx/snippets/proxy-headers.conf — it DUPLICATES one in mapnjt.confnginx -t fails. Put per-location in the multimodal site file. Backups → ~/nginx-backups/.
  • res-9 GeoJSON iso (107K) ≈ 20 MB EXCEEDS MongoDB's 16 MB doc limit; res-8 ≈ 3 MB fits; store compact, not GeoJSON.
  • OTP-NE plan: /otp/routers/default/plan?fromPlace=lat,lon&toPlace=lat,lon&date=2026-06-17&time=8:00am&mode=TRANSIT,WALK. accessMode=car_park = the P&R reference. OTP-NE covers June 2026; GPU feed covers April (service_date 20260415) — cross-date weekday compare OK at ±few min.
  • Playwright = /home/krish/gpu-pilot/hta/pwenv/bin/python; shots → multimodal/shots/.
  • geo2 = IP 172.26.1.151 (hostname doesn't resolve from geocoder).

Comments