Repository navigation
GridInterface: the shared grid contract - #6
Open
asinghvi17 wants to merge 31 commits into
Open
asinghvi17 wants to merge 31 commits into
asinghvi17 wants to merge 31 commits into
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…y walk Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hbours, collections, keyed dual, lazy chunks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…, alignment, keyed dual, dual tiling, subset algebra, sampled chunks, hierarchy obligations; tests for the revised API Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ALPix vertices, rooted halo/border, storage chunks, CopernicusDEM root index; CR bridge on GridAndTree with split_weight forwarding and raster tiles Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…arks Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…r huge analytic grids Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…c halo Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…bs on analytic grids Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…he shim GridInterface now depends on the two GeometryOps sub-packages (resolved by path from the as/split-unitsphericalgeometrycore worktree) instead of lib/SpatialTreeInterfaceShim. split_weight is STI's function; subtree_indices is answered lazily by HierarchyCursor and SelectionCursor through a frontier primitive, forwarded by GridAndTree and the CR bridge. Fixes group nodes under a RootIndex returning their parent's window, with a regression testset. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
…rtex numbering treeify(grid; leaf_capacity = Balanced() | ForSweeps() | ForQueries() | n) is the tree entry; providers map intents to integers through leaf_capacity(grid, hint) and write one integer builder. AbstractWrappedGrid forwards every verb to parent(g) from one list; GridAndTree, ChunkedGrid (mockchunks) and GridAndVertices are small wrappers over it. The extension's IdDict memos and clear_caches! are gone: fallbacks build a ForQueries tree per call and GridAndTree is the cache. Traits are instance-only. Vertex numbering is a provider hook: vertex_numbering_is_analytic(grid) lets a provider answer the dense vertex verbs in O(1), dual(grid) then holds nothing, and the derived numbering or geometric table is built only where it must be. The HEALPix adapter numbers its vertices by face arithmetic. Conformance gains the intent, wrapper-forwarding, laziness and vertex numbering laws. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
GridInterface.Structured holds the five face hooks (nfaces, facesize, facevertex, faceposition, facecell), the optional face axes, and the seam hooks facecross and facefan, from which corners, extents, the per-face TopDownQuadtreeCursor under a FaceRootTree, TileIndices/TileChunks, axis-floor or walking cellat, aligned neighbours and analytic vertices derive. CellBasedGrid, RegularGrid and ExplicitPolygonGrid are copied from CR with their constructors; CR itself is untouched and its grids reach GridInterface as Structured twins through the adapter. Neighbours and vertex fans are stack-allocated SmallInts (now a core type). Seams are arithmetic through facecross; the shared-vertex border scan is the conformance suite's oracle, not runtime. Periodic and collapsed axes are detected with a tolerance or stated through constructor keywords. Gates: every node extent of the Structured quadtree is bit-equal to CR's cursor on all of CR's test grids, and regridding through the twins is bit-identical to CR's own path. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
GridInterfaceConformance takes DGG's engineering: has_nonfallback_method (a fallback answering in place of a declared analytic trait is a failure), seeded sampling with the seed in the report header, test_grid/test_system emitting one @test per law and @test_skip per unclaimed suite, and a Mocks module with DGG's CubeSystem plus single-fault wrappers that each break exactly one law. New laws: tree (leaves emit 1:n once, node covers leaf geometry, O(1) leaf re-read, all three intents, subtree_indices is the leaf walk), wrapper forwarding, structured face round-trips, rings concatenate to discs, declared-analytic providers, CCW vertex fans, inference, and the hierarchy laws (children partition the next level, descendant_range against a recursion oracle). The lib's own test proves every mock fails only its family and every prototype grid passes. Also: SelectionCursor's subtree_indices follows STI's traversal order; the wrapper laws sample instead of enumerating so the 6.9e10-cell CopernicusDEM L1 grid passes check_grid in about 12 s, which the prototype conformance script now runs. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Replaces the Int-only SmallInts with the generic SmallVector{N,T} that
DiscreteGlobalGrids and ConservativeRegridding already return: capacity N,
runtime length, no heap, any element type, so a hexagon's five or six corners
and a vertex fan are the same shape across the stack. GridInterface re-exports
SmallVector.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
DiscreteGlobalGrids now answers GridInterface directly, so prototype/adapters/DGGAdapter.jl goes and the prototype scripts, bench and revision bench use DGG itself (treeify intent assertions added to conformance.jl; explicit `using GridInterface:` for cellat, cell_extent and the DE-9IM predicates). The untyped `level(grid) = nothing` fallback no longer swallows cell indices. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
FaceSeams builds a cubed-sphere/HEALPix seam table from the face corner vertices (with a verified cross-back) and answers facecross through seamcross. MaskedCursor is the quadtree of a structured Subset (leaves filtered by membership), used by treeify(::Subset) and subtree(grid, cells). facecolumnmajor lets a face declare a non-column-major position layout (ClimaCore's Gilbert order, ring-ordered full grids); TileChunks sorts such chunks and the pole fan goes through faceposition. The CR adapter keeps only the bridge and `structured`; Healpix maps now come through ConservativeRegridding's HealpixMapGrid. cr_parity.jl compares CR's tree path with the provider path pair by pair. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
blockextent(grid, f, ir, jr) is the documented, exported seam the quadtree, tiles and cell extents call, so a provider with an analytic block extent (GlobalRegridding's raster view) overrides it instead of a private function. The CR adapter and the one-off parity scripts are gone: ConservativeRegridding's engine now takes grids directly, and the prototype bench and conformance scripts call it as such. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
GlobalRegridding's raster chunks are lazy tile indices with an O(1) tree. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- `subtree(grid, cells; leaf_capacity)` is now `treeify(grid, n)` restricted to `cells` by a generic `MaskedCursor` (tight root, `position_span` pruning, leaf filtering), for any provider's tree. `treeify(::Subset)` is the same restriction emitting subset positions. `hierarchy_subtree` goes. - `extent_is_expensive` is removed: node cost is `STI.node_extent_is_expensive` on the tree type; bucketed hierarchy leaves build their entries once per visit, one-cell leaves stay lazy. - Type-stable `HierarchyCursor` child iteration. - Conformance: laws for `subtree` restricting `treeify`'s tree and for declared face numbering; property tests for the restriction. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…hes; stop tracking manifests Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- Join main's PkgTemplates history, keeping this branch's code. Take the repo's UUID (ae69c2d7) and author list. - CI tests Julia 1.11 (oldest with `[sources]`), 1 and pre on three OSes, runs GridInterfaceConformance's suite, and builds the docs. - Docs: API pages for GridInterface and GridInterface.Structured; the docs environment gets the split GeometryOps sources. - Add Random to the test environment. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
1.11 cannot meet the zero-allocation laws and ignores dependencies' [sources]. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
CI stays on 1.12+, where the zero-allocation laws hold. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
On Julia 1.11 the compiler leaves 16-304 bytes behind the same code that is allocation-free on 1.12, so every zero-allocation check failed there and nothing else did. - Conformance: `allocation_verdict(bytes)` turns a byte count into `:pass`, `:fail` (1.12+) or `:broken` (older Julia); the two "allocates nothing" laws use it. `:broken` is printed, counts against no family in `family_status`, and is a `@test_broken` (named in one @info) in the test forms, so a downstream suite passes on 1.11. - Tests: `@test_noalloc f(...)` records a non-zero count as broken below 1.12 and still passes a zero count; `expected_fails` drops the allocation laws from an expected failure list there. The lib's own suite counts skips apart from broken laws and expects the Stateful mock's sweep to be broken, not failed, on 1.11. - CI stays at 1.12, 1 and pre, with the reason in the workflow; README states the 1.11 requirement and the 1.12+ allocation guarantee. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
- A "Trees and restriction" page describes the contracts: `treeify` as the provider's seam (`n::Integer`), `subtree` as the generic `MaskedCursor` restriction of the grid's own tree pruned by `position_span`, `SubtreeCapacity` as the reason the generic `treeify` can answer `nothing`, node extent cost on tree node types through `SpatialTreeInterface.node_extent_is_expensive`, and leaf entries built once per visit. - The API reference is one page per family under docs/src/api/, each with a short intro and an explicit `@docs` block covering every docstring in GridInterface and GridInterface.Structured. - `split_weight` and `subtree_indices` get GridInterface docstrings (they are SpatialTreeInterface's verbs, which Documenter will not show from an unlisted module), and `seamcross` gets its own docstring. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…urning The dual law "vertex fans wind CCW about the vertex" wound every fan's cell centroids as a closed ring about the vertex. That is the right test when the vertex is interior; an open fan (vertex_isopen) has the vertex on the grid's boundary, so its centroids form an arc beside it that turns by nothing about it in any order, and a correctly ordered fan failed. Open fans now pass when their centroid azimuths about the vertex step CCW with a total sweep short of a full turn (is_ccw_open_sequence); closed fans keep ring_is_ccw. Azimuths come from _azimuth on the grid's manifold, as the declared-winding law already does. Tests: a RegularGrid(Spherical(), -40:10:40, 50:10:90) reaching the north pole passes every law, its BrokenDual fails only the dual family and names this law, and the helper is checked across the azimuth branch cut. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Separate rectangular storage from shared-vertex geometry while retaining optimized native maps. Stream planar polygon bounds and inline corner construction; document minimal provider recipes and strengthen neighbour conformance checks. Validated exact source: GridInterface 2902 passed, 1 existing skip; GridInterfaceConformance 116 passed; generic multiface defaults 60 passed.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The first implementation of GridInterface: a shared contract for grids on the plane and the sphere, used by ConservativeRegridding.jl (JuliaGeo/ConservativeRegridding.jl#155) and DiscreteGlobalGrids.jl (JuliaGeo/DiscreteGlobalGrids.jl#125).
GridAndTree. Small answers are stack-allocatedSmallVectors.treeify(grid; leaf_capacity = Balanced() | ForSweeps() | ForQueries() | n)builds the grid's own tree.subtree(grid, cells)restricts that tree to a subset (tight root,position_spanpruning, leaf filtering). Node cost isSTI.node_extent_is_expensiveon the tree type.GridInterface.Structured: the face protocol (faces, axes, seams, fans), quadtrees, tiles and masked subsets. It takes CR's grids.lib/GridInterfaceConformance: laws every provider is checked against, with mocks that each fail exactly one family.The history is unrelated to
main's template commits; this PR merges the template in. It keeps the repo's UUID (ae69c2d7), and the downstream PRs use it.Depends on GeometryOps.jl
as/split-unitsphericalgeometrycore(JuliaGeo/GeometryOps.jl#524) through[sources], so CI starts at Julia 1.12.CI runs the tests on 1.12, 1 and pre on Linux, macOS and Windows, runs GridInterfaceConformance's suite, and builds the docs.
🤖 Generated with Claude Code