xarray-spatial 0.9.7__tar.gz → 0.9.8__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/bench.md +6 -6
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/efficiency-audit.md +1 -1
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/release-major.md +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/release-minor.md +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/release-patch.md +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/sweep-accuracy.md +64 -25
- xarray_spatial-0.9.8/.claude/commands/sweep-performance.md +325 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/sweep-security.md +66 -25
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/validate.md +1 -1
- xarray_spatial-0.9.8/.claude/sweep-accuracy-state.csv +19 -0
- xarray_spatial-0.9.8/.claude/sweep-performance-state.csv +46 -0
- xarray_spatial-0.9.8/.claude/sweep-security-state.csv +50 -0
- xarray_spatial-0.9.8/.gitattributes +4 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/workflows/benchmarks.yml +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/workflows/test.yml +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/CHANGELOG.md +52 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/CONTRIBUTING.md +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/PKG-INFO +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/README.md +2 -2
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/PKG-INFO +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/SOURCES.txt +6 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/_version.py +3 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/aspect.py +4 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/cost_distance.py +98 -5
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/curvature.py +8 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/dasymetric.py +92 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/diffusion.py +170 -29
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/edge_detection.py +6 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/emerging_hotspots.py +58 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/erosion.py +97 -23
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/experimental/min_observable_height.py +39 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/focal.py +53 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geodesic.py +49 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/__init__.py +16 -9
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_writer.py +68 -25
- xarray_spatial-0.9.8/xrspatial/geotiff/tests/test_predictor_fp_write_1313.py +203 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/glcm.py +17 -4
- xarray_spatial-0.9.8/xrspatial/gpu_rtx/_memory.py +60 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/gpu_rtx/hillshade.py +4 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/gpu_rtx/viewshed.py +4 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/basin_d8.py +89 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/fill_d8.py +88 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_accumulation_d8.py +89 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_accumulation_dinf.py +92 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_accumulation_mfd.py +91 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_length_d8.py +90 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_length_dinf.py +91 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_length_mfd.py +94 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/hand_d8.py +94 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/hand_dinf.py +95 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/hand_mfd.py +94 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/stream_link_d8.py +93 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/stream_link_dinf.py +95 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/stream_link_mfd.py +94 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/stream_order_d8.py +96 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/stream_order_dinf.py +99 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/stream_order_mfd.py +99 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_basin_d8.py +73 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_fill_d8.py +73 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_accumulation_d8.py +58 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_accumulation_dinf.py +58 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_accumulation_mfd.py +57 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_length_d8.py +69 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_length_dinf.py +75 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_length_mfd.py +74 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_hand_d8.py +84 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_hand_dinf.py +88 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_hand_mfd.py +84 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_stream_link_d8.py +77 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_stream_link_dinf.py +77 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_stream_link_mfd.py +94 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_stream_order_d8.py +77 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_stream_order_dinf.py +80 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_stream_order_mfd.py +92 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_watershed_d8.py +88 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_watershed_dinf.py +84 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_watershed_mfd.py +88 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/watershed_d8.py +89 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/watershed_dinf.py +90 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/watershed_mfd.py +89 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/interpolate/_kriging.py +74 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/kde.py +52 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mahalanobis.py +107 -2
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mcda/combine.py +43 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mcda/weights.py +15 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/morphology.py +50 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/multispectral.py +89 -1
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/resample.py +99 -3
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/sieve.py +89 -18
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/sky_view_factor.py +79 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/slope.py +4 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/surface_distance.py +94 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/terrain_metrics.py +51 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_cost_distance.py +153 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_curvature.py +12 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_dasymetric.py +128 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_diffusion.py +177 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_edge_detection.py +27 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_emerging_hotspots.py +84 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_erosion.py +135 -1
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_focal.py +37 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_geodesic_aspect.py +35 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_geodesic_slope.py +41 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_glcm.py +42 -3
- xarray_spatial-0.9.8/xrspatial/tests/test_gpu_rtx_memory.py +175 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_interpolation.py +89 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_kde.py +38 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_mahalanobis.py +86 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_mcda.py +118 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_min_observable_height.py +56 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_morphology.py +51 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_multispectral.py +122 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_resample.py +52 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_sieve.py +30 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_sky_view_factor.py +84 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_surface_distance.py +119 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_terrain_metrics.py +17 -0
- xarray_spatial-0.9.7/.claude/commands/sweep-performance.md +0 -502
- xarray_spatial-0.9.7/.claude/sweep-accuracy-state.json +0 -22
- xarray_spatial-0.9.7/.claude/sweep-performance-state.json +0 -50
- xarray_spatial-0.9.7/.claude/sweep-security-state.json +0 -108
- xarray_spatial-0.9.7/.gitattributes +0 -2
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/backend-parity.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/dask-notebook.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/new-issues.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/review-pr.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/rockout.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.claude/commands/user-guide-notebook.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.efficiency-audit-baseline.json +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.efficiency-audit-baseline.prev.json +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/ISSUE_TEMPLATE/feature-proposal.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/labeler.yml +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/pull_request_template.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/workflows/labeler.yml +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.github/workflows/pypi-publish.yml +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.gitignore +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/.readthedocs.yml +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/CODE_OF_CONDUCT.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/Citation-styles.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/LICENSE.txt +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/MANIFEST.in +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/RELEASE.md +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/codecov.yml +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/pyproject.toml +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/setup.cfg +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/setup.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/dependency_links.txt +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/entry_points.txt +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/not-zip-safe +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/requires.txt +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xarray_spatial.egg-info/top_level.txt +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/__main__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/accessor.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/analytics.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/balanced_allocation.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/bilateral.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/bump.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/classify.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/contour.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/convolution.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/corridor.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/dataset_support.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/sentinel-2/blue_band.nc +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/sentinel-2/green_band.nc +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/sentinel-2/nir_band.nc +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/sentinel-2/red_band.nc +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/sentinel-2/swir1_band.nc +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/datasets/sentinel-2/swir2_band.nc +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/diagnostics.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/experimental/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/fire.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/flood.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_compression.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_dtypes.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_geotags.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_gpu_decode.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_header.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_reader.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/_vrt.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/bench_vs_rioxarray.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/conftest.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_accessor_io.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_accuracy_1081.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_cog.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_compression.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_compression_level.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_dtype_read.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_edge_cases.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_features.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_geotags.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_header.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_jpeg.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_jpeg2000.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_lerc.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_lz4.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_predictor_multisample.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_reader.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_security.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_streaming_write.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_vrt_write.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/geotiff/tests/test_writer.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/gpu_rtx/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/gpu_rtx/cuda_utils.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/gpu_rtx/mesh_utils.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hillshade.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/_boundary_store.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_direction_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_direction_dinf.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_direction_mfd.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_path_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_path_dinf.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/flow_path_mfd.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/sink_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/conftest.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_direction_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_direction_dinf.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_direction_mfd.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_path_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_path_dinf.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_flow_path_mfd.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_sink_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_snap_pour_point_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/tests/test_twi_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/hydro/twi_d8.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/interpolate/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/interpolate/_idw.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/interpolate/_spline.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/interpolate/_validation.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mcda/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mcda/constrain.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mcda/sensitivity.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/mcda/standardize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/normalize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/pathfinding.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/perlin.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/polygon_clip.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/polygonize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/preview.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/proximity.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/rasterize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_crs_utils.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_datum_grids.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_grid.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_interpolate.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_itrf.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_lite_crs.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_merge.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_projections.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_projections_cuda.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_transform.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/_vertical.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/at_bev_AT_GIS_GRID.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/au_icsm_A66_National_13_09_01.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/be_ign_bd72lb72_etrs89lb08.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/ch_swisstopo_CHENyx06_ETRS.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/de_adv_BETA2007.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/es_ign_SPED2ETV2.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/nl_nsgi_rdcorr2018.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/pt_dgt_D73_ETRS89_geo.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/uk_os_OSTN15_NTv2_OSGBtoETRS.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/us_nga_egm96_15.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/us_noaa_alaska.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/us_noaa_conus.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/us_noaa_hawaii.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/us_noaa_nadcon5_nad27_nad83_1986_conus.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/reproject/grids/us_noaa_prvi.tif +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/terrain.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/__init__.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/bench_reproject_vs_rioxarray.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/conftest.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/general_checks.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_accessor.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_analytics.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_aspect.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_balanced_allocation.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_bilateral.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_bump.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_classify.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_contour.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_corridor.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_dask_cupy_gaps.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_dask_laziness.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_dataset_support.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_datasets.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_diagnostics.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_fire.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_flood.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_fused_overlap.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_glcm_metric_order.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_hillshade.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_hypsometric_integral.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_lite_crs.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_morphology_derived.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_multi_overlap.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_normalize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_northness_eastness.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_pathfinding.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_perlin.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_polygon_clip.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_polygonize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_preview.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_proximity.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_rasterize.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_rasterize_accuracy.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_rechunk_no_shuffle.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_reproject.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_sieve_gdal_parity.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_slope.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_terrain.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_utils.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_validation.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_viewshed.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_visibility.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/tests/test_zonal.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/utils.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/viewshed.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/visibility.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/worley.py +0 -0
- {xarray_spatial-0.9.7 → xarray_spatial-0.9.8}/xrspatial/zonal.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Bench: Local Performance Comparison
|
|
2
2
|
|
|
3
|
-
Run ASV benchmarks for the current branch against
|
|
3
|
+
Run ASV benchmarks for the current branch against main and report regressions
|
|
4
4
|
and improvements. The prompt is: $ARGUMENTS
|
|
5
5
|
|
|
6
6
|
---
|
|
@@ -9,7 +9,7 @@ and improvements. The prompt is: $ARGUMENTS
|
|
|
9
9
|
|
|
10
10
|
1. If $ARGUMENTS names specific benchmark classes or functions (e.g. `Slope`,
|
|
11
11
|
`flow_accumulation`), use those directly.
|
|
12
|
-
2. If $ARGUMENTS is empty or says "auto", run `git diff origin/
|
|
12
|
+
2. If $ARGUMENTS is empty or says "auto", run `git diff origin/main --name-only`
|
|
13
13
|
to find changed source files under `xrspatial/`. Map each changed file to the
|
|
14
14
|
corresponding benchmark module in `benchmarks/benchmarks/`. Use the filename
|
|
15
15
|
and imports to match (e.g. changes to `slope.py` map to `benchmarks/benchmarks/slope.py`).
|
|
@@ -30,7 +30,7 @@ and improvements. The prompt is: $ARGUMENTS
|
|
|
30
30
|
Run ASV in continuous-comparison mode from the `benchmarks/` directory:
|
|
31
31
|
|
|
32
32
|
```bash
|
|
33
|
-
cd benchmarks && asv continuous origin/
|
|
33
|
+
cd benchmarks && asv continuous origin/main HEAD -b "<regex>" -e
|
|
34
34
|
```
|
|
35
35
|
|
|
36
36
|
Where `<regex>` is a pattern matching the benchmark classes identified in Step 1
|
|
@@ -64,7 +64,7 @@ Parse the output and classify each result:
|
|
|
64
64
|
## Step 5 -- Generate the report
|
|
65
65
|
|
|
66
66
|
```
|
|
67
|
-
## Benchmark Report: <branch> vs
|
|
67
|
+
## Benchmark Report: <branch> vs main
|
|
68
68
|
|
|
69
69
|
### Changed files
|
|
70
70
|
- <list of changed source files>
|
|
@@ -74,7 +74,7 @@ Parse the output and classify each result:
|
|
|
74
74
|
|
|
75
75
|
### Results
|
|
76
76
|
|
|
77
|
-
| Benchmark |
|
|
77
|
+
| Benchmark | main | HEAD | Ratio | Status |
|
|
78
78
|
|------------------------------------|-----------|-----------|-------|------------|
|
|
79
79
|
| slope.Slope.time_numpy | 3.45 ms | 3.51 ms | 1.02x | UNCHANGED |
|
|
80
80
|
| slope.Slope.time_dask_numpy | 8.12 ms | 4.23 ms | 0.52x | IMPROVED |
|
|
@@ -124,4 +124,4 @@ Do NOT write benchmark files automatically. Report the gap and propose, then wai
|
|
|
124
124
|
analysis (unless the user explicitly asks for a benchmark to be written in
|
|
125
125
|
response to Step 6).
|
|
126
126
|
- If $ARGUMENTS says "compare <branch1> <branch2>", run
|
|
127
|
-
`asv continuous <branch1> <branch2>` instead of the default origin/
|
|
127
|
+
`asv continuous <branch1> <branch2>` instead of the default origin/main vs HEAD.
|
|
@@ -267,7 +267,7 @@ Thresholds: IMPROVED < 0.8x, REGRESSION > 1.2x, else UNCHANGED.
|
|
|
267
267
|
- If $ARGUMENTS includes a severity filter (e.g. "high only"), only report
|
|
268
268
|
findings at that severity level.
|
|
269
269
|
- If $ARGUMENTS includes "diff" or "changed", restrict the audit to files
|
|
270
|
-
changed on the current branch vs origin/
|
|
270
|
+
changed on the current branch vs origin/main.
|
|
271
271
|
- Baseline benchmark scripts are disposable. Clean up `/tmp/` scripts after
|
|
272
272
|
capturing results.
|
|
273
273
|
- The 512x512 array size is a default. If $ARGUMENTS includes a size like
|
|
@@ -16,7 +16,7 @@ $ARGUMENTS
|
|
|
16
16
|
## Step 2 -- Create a release branch
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
git checkout
|
|
19
|
+
git checkout main && git pull
|
|
20
20
|
git checkout -b release/vX.Y.Z
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -49,7 +49,7 @@ git push -u origin release/vX.Y.Z
|
|
|
49
49
|
|
|
50
50
|
## Step 5 -- Verify CI
|
|
51
51
|
|
|
52
|
-
1. Run `gh pr create --title "Release vX.Y.Z" --body "Changelog update for vX.Y.Z major release."` to open a PR against
|
|
52
|
+
1. Run `gh pr create --title "Release vX.Y.Z" --body "Changelog update for vX.Y.Z major release."` to open a PR against main.
|
|
53
53
|
2. Wait for CI:
|
|
54
54
|
```bash
|
|
55
55
|
gh pr checks <PR_NUMBER> --watch
|
|
@@ -65,7 +65,7 @@ gh pr merge <PR_NUMBER> --merge --delete-branch
|
|
|
65
65
|
## Step 7 -- Tag the release
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
git checkout
|
|
68
|
+
git checkout main && git pull
|
|
69
69
|
git tag -a vX.Y.Z -m "Version X.Y.Z"
|
|
70
70
|
git push origin vX.Y.Z
|
|
71
71
|
```
|
|
@@ -16,7 +16,7 @@ $ARGUMENTS
|
|
|
16
16
|
## Step 2 -- Create a release branch
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
git checkout
|
|
19
|
+
git checkout main && git pull
|
|
20
20
|
git checkout -b release/vX.Y.Z
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -49,7 +49,7 @@ git push -u origin release/vX.Y.Z
|
|
|
49
49
|
|
|
50
50
|
## Step 5 -- Verify CI
|
|
51
51
|
|
|
52
|
-
1. Run `gh pr create --title "Release vX.Y.Z" --body "Changelog update for vX.Y.Z minor release."` to open a PR against
|
|
52
|
+
1. Run `gh pr create --title "Release vX.Y.Z" --body "Changelog update for vX.Y.Z minor release."` to open a PR against main.
|
|
53
53
|
2. Wait for CI:
|
|
54
54
|
```bash
|
|
55
55
|
gh pr checks <PR_NUMBER> --watch
|
|
@@ -65,7 +65,7 @@ gh pr merge <PR_NUMBER> --merge --delete-branch
|
|
|
65
65
|
## Step 7 -- Tag the release
|
|
66
66
|
|
|
67
67
|
```bash
|
|
68
|
-
git checkout
|
|
68
|
+
git checkout main && git pull
|
|
69
69
|
git tag -a vX.Y.Z -m "Version X.Y.Z"
|
|
70
70
|
git push origin vX.Y.Z
|
|
71
71
|
```
|
|
@@ -16,7 +16,7 @@ $ARGUMENTS
|
|
|
16
16
|
## Step 2 -- Create a release branch
|
|
17
17
|
|
|
18
18
|
```bash
|
|
19
|
-
git checkout
|
|
19
|
+
git checkout main && git pull
|
|
20
20
|
git checkout -b release/vX.Y.Z
|
|
21
21
|
```
|
|
22
22
|
|
|
@@ -46,7 +46,7 @@ git push -u origin release/vX.Y.Z
|
|
|
46
46
|
|
|
47
47
|
## Step 5 -- Verify CI
|
|
48
48
|
|
|
49
|
-
1. Run `gh pr create --title "Release vX.Y.Z" --body "Changelog update for vX.Y.Z patch release."` to open a PR against
|
|
49
|
+
1. Run `gh pr create --title "Release vX.Y.Z" --body "Changelog update for vX.Y.Z patch release."` to open a PR against main.
|
|
50
50
|
2. Wait for CI:
|
|
51
51
|
```bash
|
|
52
52
|
gh pr checks <PR_NUMBER> --watch
|
|
@@ -62,7 +62,7 @@ gh pr merge <PR_NUMBER> --merge --delete-branch
|
|
|
62
62
|
## Step 7 -- Tag the release
|
|
63
63
|
|
|
64
64
|
```bash
|
|
65
|
-
git checkout
|
|
65
|
+
git checkout main && git pull
|
|
66
66
|
git tag -a vX.Y.Z -m "Version X.Y.Z"
|
|
67
67
|
git push origin vX.Y.Z
|
|
68
68
|
```
|
|
@@ -36,28 +36,30 @@ Store results in memory -- do NOT write intermediate files.
|
|
|
36
36
|
|
|
37
37
|
## Step 2 -- Load inspection state
|
|
38
38
|
|
|
39
|
-
Read `.claude/sweep-accuracy-state.
|
|
39
|
+
Read `.claude/sweep-accuracy-state.csv`.
|
|
40
40
|
|
|
41
41
|
If it does not exist, treat every module as never-inspected.
|
|
42
42
|
|
|
43
43
|
If `$ARGUMENTS` contains `--reset-state`, delete the file and treat
|
|
44
44
|
everything as never-inspected.
|
|
45
45
|
|
|
46
|
-
State file schema:
|
|
47
|
-
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
"slope": {
|
|
52
|
-
"last_inspected": "2026-03-28T14:00:00Z",
|
|
53
|
-
"issue": 1042,
|
|
54
|
-
"severity_max": "HIGH",
|
|
55
|
-
"categories_found": [1, 3]
|
|
56
|
-
}
|
|
57
|
-
}
|
|
58
|
-
}
|
|
46
|
+
State file schema (one row per module):
|
|
47
|
+
|
|
48
|
+
```
|
|
49
|
+
module,last_inspected,issue,severity_max,categories_found,notes
|
|
50
|
+
slope,2026-03-28,1042,HIGH,1;3,"optional single-line notes"
|
|
59
51
|
```
|
|
60
52
|
|
|
53
|
+
- `categories_found` is a semicolon-separated integer list (empty when null).
|
|
54
|
+
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
55
|
+
every module stays exactly one line.
|
|
56
|
+
|
|
57
|
+
The file is registered with `merge=union` in `.gitattributes`, so two
|
|
58
|
+
parallel sweeps touching different modules auto-merge without conflict.
|
|
59
|
+
A transient duplicate-row state can occur after a merge if both branches
|
|
60
|
+
modified the same module; the read-update-write cycle in step 5 keys rows
|
|
61
|
+
by `module` and last-write-wins, so the next write cleans up.
|
|
62
|
+
|
|
61
63
|
## Step 3 -- Score each module
|
|
62
64
|
|
|
63
65
|
```
|
|
@@ -196,14 +198,49 @@ xrspatial/tests/general_checks.py for the cross-backend comparison helpers.
|
|
|
196
198
|
For MEDIUM/LOW issues, document them but do not fix.
|
|
197
199
|
|
|
198
200
|
5. After finishing (whether you found issues or not), update the inspection
|
|
199
|
-
state file .claude/sweep-accuracy-state.
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
201
|
+
state file .claude/sweep-accuracy-state.csv. The file is row-per-module
|
|
202
|
+
CSV with header:
|
|
203
|
+
|
|
204
|
+
`module,last_inspected,issue,severity_max,categories_found,notes`
|
|
205
|
+
|
|
206
|
+
Use this Python pattern to read, update, and write it (do NOT hand-edit
|
|
207
|
+
the file -- always go through csv.DictReader / csv.DictWriter so quoting
|
|
208
|
+
stays consistent):
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
import csv
|
|
212
|
+
from pathlib import Path
|
|
213
|
+
|
|
214
|
+
path = Path(".claude/sweep-accuracy-state.csv")
|
|
215
|
+
header = ["module", "last_inspected", "issue", "severity_max",
|
|
216
|
+
"categories_found", "notes"]
|
|
217
|
+
|
|
218
|
+
rows = {}
|
|
219
|
+
if path.exists():
|
|
220
|
+
with path.open() as f:
|
|
221
|
+
for r in csv.DictReader(f):
|
|
222
|
+
rows[r["module"]] = r # last write wins on dupes
|
|
223
|
+
|
|
224
|
+
rows["{module}"] = {
|
|
225
|
+
"module": "{module}",
|
|
226
|
+
"last_inspected": "<today's ISO date, e.g. 2026-04-27>",
|
|
227
|
+
"issue": "<issue number from rockout, or empty string>",
|
|
228
|
+
"severity_max": "<HIGH|MEDIUM|LOW, or empty>",
|
|
229
|
+
"categories_found": "<semicolon-joined ints, e.g. 1;3, or empty>",
|
|
230
|
+
"notes": "<single-line notes (replace any newlines with spaces), or empty>",
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
with path.open("w", newline="") as f:
|
|
234
|
+
w = csv.DictWriter(f, fieldnames=header, quoting=csv.QUOTE_MINIMAL)
|
|
235
|
+
w.writeheader()
|
|
236
|
+
for m in sorted(rows):
|
|
237
|
+
w.writerow(rows[m])
|
|
238
|
+
```
|
|
239
|
+
|
|
240
|
+
Use empty strings (not `null`) for missing values. Set `issue` to the
|
|
241
|
+
issue number when one was filed, otherwise leave it empty.
|
|
242
|
+
|
|
243
|
+
Then `git add .claude/sweep-accuracy-state.csv` and commit it to the
|
|
207
244
|
worktree branch so the state update is included in the PR.
|
|
208
245
|
|
|
209
246
|
Important:
|
|
@@ -236,7 +273,7 @@ State is updated by the subagents themselves (see agent prompt step 5).
|
|
|
236
273
|
After completion, verify state with:
|
|
237
274
|
|
|
238
275
|
```
|
|
239
|
-
|
|
276
|
+
column -t -s, .claude/sweep-accuracy-state.csv | less
|
|
240
277
|
```
|
|
241
278
|
|
|
242
279
|
To reset all tracking: `/sweep-accuracy --reset-state`
|
|
@@ -248,8 +285,10 @@ To reset all tracking: `/sweep-accuracy --reset-state`
|
|
|
248
285
|
- Do NOT modify any source files directly. Subagents handle fixes via /rockout.
|
|
249
286
|
- Keep the output concise -- the table and agent dispatch are the deliverables.
|
|
250
287
|
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no exclusions.
|
|
251
|
-
- State file (`.claude/sweep-accuracy-state.
|
|
252
|
-
|
|
288
|
+
- State file (`.claude/sweep-accuracy-state.csv`) is tracked in git, with
|
|
289
|
+
`merge=union` set in `.gitattributes` so parallel sweeps touching
|
|
290
|
+
different modules auto-merge. Subagents must `git add` and commit it so
|
|
291
|
+
the state update lands in the PR.
|
|
253
292
|
- For subpackage modules (geotiff, reproject, hydro), the subagent should read
|
|
254
293
|
ALL `.py` files in the subpackage directory, not just `__init__.py`.
|
|
255
294
|
- Only flag patterns that are ACTUALLY present in the code. Do not report
|
|
@@ -0,0 +1,325 @@
|
|
|
1
|
+
# Performance Sweep: Dispatch subagents to audit and fix performance issues
|
|
2
|
+
|
|
3
|
+
Audit xrspatial modules for performance bottlenecks, OOM risk under 30TB dask
|
|
4
|
+
workloads, and backend-specific anti-patterns. Subagents fix HIGH-severity
|
|
5
|
+
findings via /rockout in the same agent that did the audit, in parallel.
|
|
6
|
+
|
|
7
|
+
Optional arguments: $ARGUMENTS
|
|
8
|
+
(e.g. `--top 5`, `--exclude slope,aspect`, `--only-io`, `--reset-state`)
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
## Step 0 -- Parse arguments
|
|
13
|
+
|
|
14
|
+
Parse $ARGUMENTS for these flags (multiple may combine):
|
|
15
|
+
|
|
16
|
+
| Flag | Effect |
|
|
17
|
+
|------|--------|
|
|
18
|
+
| `--top N` | Audit only the top N scored modules (default: 3) |
|
|
19
|
+
| `--exclude mod1,mod2` | Remove named modules from scope |
|
|
20
|
+
| `--only-terrain` | Restrict to: slope, aspect, curvature, terrain, terrain_metrics, hillshade, sky_view_factor |
|
|
21
|
+
| `--only-focal` | Restrict to: focal, convolution, morphology, bilateral, edge_detection, glcm |
|
|
22
|
+
| `--only-hydro` | Restrict to: flood, cost_distance, geodesic, surface_distance, viewshed, erosion, diffusion |
|
|
23
|
+
| `--only-io` | Restrict to: geotiff, reproject, rasterize, polygonize |
|
|
24
|
+
| `--reset-state` | Delete `.claude/sweep-performance-state.csv` and treat all modules as never-inspected |
|
|
25
|
+
| `--no-fix` | Audit only; subagents do not run /rockout. Useful for re-triage without producing PRs. |
|
|
26
|
+
| `--high-only` | Drop modules whose state row shows zero HIGH findings from the last triage within the past 30 days. |
|
|
27
|
+
|
|
28
|
+
## Step 1 -- Discover modules in scope
|
|
29
|
+
|
|
30
|
+
Enumerate all candidate modules. For each, record its file path(s):
|
|
31
|
+
|
|
32
|
+
**Single-file modules:** Every `.py` file directly under `xrspatial/`, excluding
|
|
33
|
+
`__init__.py`, `_version.py`, `__main__.py`, `utils.py`, `accessor.py`,
|
|
34
|
+
`preview.py`, `dataset_support.py`, `diagnostics.py`, `analytics.py`.
|
|
35
|
+
|
|
36
|
+
**Subpackage modules:** The `geotiff/`, `reproject/`, and `hydro/` directories
|
|
37
|
+
under `xrspatial/`. Treat each subpackage as a single audit unit. List all
|
|
38
|
+
`.py` files within each (excluding `__init__.py`).
|
|
39
|
+
|
|
40
|
+
Apply `--only-*` and `--exclude` filters from Step 0 to narrow the list.
|
|
41
|
+
|
|
42
|
+
Store the filtered module list in memory (do NOT write intermediate files).
|
|
43
|
+
|
|
44
|
+
## Step 2 -- Gather metadata and score each module
|
|
45
|
+
|
|
46
|
+
For every module in scope, collect:
|
|
47
|
+
|
|
48
|
+
| Field | How |
|
|
49
|
+
|-------|-----|
|
|
50
|
+
| **last_modified** | `git log -1 --format=%aI -- <path>` (for subpackages, use the most recent file) |
|
|
51
|
+
| **total_commits** | `git log --oneline -- <path> \| wc -l` |
|
|
52
|
+
| **loc** | `wc -l < <path>` (for subpackages, sum all files) |
|
|
53
|
+
| **has_dask_backend** | grep the file(s) for `_run_dask`, `map_overlap`, `map_blocks` |
|
|
54
|
+
| **has_cuda_backend** | grep the file(s) for `@cuda.jit`, `import cupy` |
|
|
55
|
+
| **is_io_module** | module is geotiff or reproject |
|
|
56
|
+
| **has_existing_bench** | a file matching the module name exists in `benchmarks/benchmarks/` |
|
|
57
|
+
|
|
58
|
+
### Load inspection state
|
|
59
|
+
|
|
60
|
+
Read `.claude/sweep-performance-state.csv`. If it does not exist, treat every
|
|
61
|
+
module as never-inspected. If `--reset-state` was set, delete the file first.
|
|
62
|
+
|
|
63
|
+
State file schema (one row per module):
|
|
64
|
+
|
|
65
|
+
```
|
|
66
|
+
module,last_inspected,oom_verdict,bottleneck,high_count,issue,notes
|
|
67
|
+
slope,2026-04-15,SAFE,compute-bound,0,,"optional single-line notes"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- `oom_verdict` is one of `SAFE`, `RISKY`, `WILL OOM`, or `N/A`.
|
|
71
|
+
- `bottleneck` is one of `IO-bound`, `memory-bound`, `compute-bound`, `graph-bound`.
|
|
72
|
+
- `issue` is normally an integer, but may be a string token like
|
|
73
|
+
`false-positive`, `fixed-in-tree`, or empty.
|
|
74
|
+
- `notes` is CSV-quoted; newlines must be flattened to spaces on write so
|
|
75
|
+
every module stays exactly one line.
|
|
76
|
+
|
|
77
|
+
The file is registered with `merge=union` in `.gitattributes`, so two
|
|
78
|
+
parallel sweeps touching different modules auto-merge without conflict.
|
|
79
|
+
A transient duplicate-row state can occur after a merge if both branches
|
|
80
|
+
modified the same module; the read-update-write cycle in the agent prompt
|
|
81
|
+
keys rows by `module` and last-write-wins, so the next write cleans up.
|
|
82
|
+
|
|
83
|
+
### Compute scores
|
|
84
|
+
|
|
85
|
+
```
|
|
86
|
+
days_since_inspected = (today - last_inspected).days # 9999 if never
|
|
87
|
+
days_since_modified = (today - last_modified).days
|
|
88
|
+
|
|
89
|
+
score = (days_since_inspected * 3)
|
|
90
|
+
+ (loc * 0.1)
|
|
91
|
+
+ (total_commits * 0.5)
|
|
92
|
+
+ (has_dask_backend * 200)
|
|
93
|
+
+ (has_cuda_backend * 150)
|
|
94
|
+
+ (is_io_module * 300)
|
|
95
|
+
- (days_since_modified * 0.2)
|
|
96
|
+
- (has_existing_bench * 100)
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
Sort modules by score descending. Apply `--top N` (default 3).
|
|
100
|
+
|
|
101
|
+
If `--high-only` is set, drop any module whose state row shows
|
|
102
|
+
`high_count == 0` AND `last_inspected` is within the last 30 days. The
|
|
103
|
+
filter only looks at past triage results — it cannot predict findings on a
|
|
104
|
+
never-inspected module.
|
|
105
|
+
|
|
106
|
+
## Step 3 -- Print the ranked table and launch subagents
|
|
107
|
+
|
|
108
|
+
### 3a. Print the ranked table
|
|
109
|
+
|
|
110
|
+
Print a markdown table showing ALL scored modules (not just selected ones),
|
|
111
|
+
sorted by score descending:
|
|
112
|
+
|
|
113
|
+
```
|
|
114
|
+
| Rank | Module | Score | Last Inspected | Dask | CUDA | IO | LOC |
|
|
115
|
+
|------|-----------------|--------|----------------|------|------|-----|------|
|
|
116
|
+
| 1 | geotiff | 30600 | never | yes | no | yes | 1400 |
|
|
117
|
+
| 2 | viewshed | 30050 | never | yes | yes | no | 800 |
|
|
118
|
+
| ... | ... | ... | ... | ... | ... | ... | ... |
|
|
119
|
+
```
|
|
120
|
+
|
|
121
|
+
### 3b. Launch subagents for the top N modules
|
|
122
|
+
|
|
123
|
+
For each of the top N modules (default 3), launch an Agent in parallel using
|
|
124
|
+
`isolation: "worktree"` and `mode: "auto"`. All N agents must be dispatched
|
|
125
|
+
in a single message so they run concurrently.
|
|
126
|
+
|
|
127
|
+
Each agent's prompt must be self-contained and follow this template (adapt
|
|
128
|
+
the module name, paths, and metadata):
|
|
129
|
+
|
|
130
|
+
~~~
|
|
131
|
+
You are auditing the xrspatial module "{module}" for performance issues.
|
|
132
|
+
|
|
133
|
+
This module has {commits} commits and {loc} lines of code.
|
|
134
|
+
|
|
135
|
+
Read these files: {module_files}
|
|
136
|
+
|
|
137
|
+
Also read xrspatial/utils.py for _validate_raster() behavior, and
|
|
138
|
+
xrspatial/tests/general_checks.py for cross-backend test helpers.
|
|
139
|
+
|
|
140
|
+
**Your task:**
|
|
141
|
+
|
|
142
|
+
1. Read all listed files thoroughly, including the matching test file(s)
|
|
143
|
+
under xrspatial/tests/.
|
|
144
|
+
|
|
145
|
+
2. Audit for these 6 categories. For each, look for the specific patterns
|
|
146
|
+
described. Only flag issues ACTUALLY present in the code.
|
|
147
|
+
|
|
148
|
+
**Cat 1 — Dask materialization**
|
|
149
|
+
- HIGH: `.values` on a dask-backed DataArray or CuPy array
|
|
150
|
+
- HIGH: `.compute()` inside a loop
|
|
151
|
+
- HIGH: `np.array()` or `np.asarray()` wrapping a dask or CuPy array
|
|
152
|
+
- MEDIUM: `da.stack()` without a following `.rechunk()`
|
|
153
|
+
|
|
154
|
+
**Cat 2 — Dask chunking and overlap**
|
|
155
|
+
- MEDIUM: `map_overlap` with depth >= chunk_size / 4
|
|
156
|
+
- MEDIUM: Missing `boundary` argument in `map_overlap`
|
|
157
|
+
- MEDIUM: Same function called twice on same input without caching
|
|
158
|
+
- MEDIUM: Python `for` loop iterating over dask chunks
|
|
159
|
+
|
|
160
|
+
**Cat 3 — GPU transfer**
|
|
161
|
+
- HIGH: `.data.get()` followed by CuPy operations (GPU→CPU→GPU round-trip)
|
|
162
|
+
- HIGH: `cupy.asarray()` inside a loop
|
|
163
|
+
- MEDIUM: Mixing NumPy and CuPy ops in same function without clear reason
|
|
164
|
+
- MEDIUM: Register pressure — count float64 local variables in `@cuda.jit`
|
|
165
|
+
kernels; flag if >20
|
|
166
|
+
- MEDIUM: Thread blocks >16x16 on kernels with >20 float64 locals
|
|
167
|
+
|
|
168
|
+
**Cat 4 — Memory allocation**
|
|
169
|
+
- MEDIUM: Unnecessary `.copy()` on arrays never mutated downstream
|
|
170
|
+
- MEDIUM: Large temporary arrays that could be fused into the kernel
|
|
171
|
+
- LOW: `np.zeros_like()` + fill loop where `np.empty()` would suffice
|
|
172
|
+
|
|
173
|
+
**Cat 5 — Numba anti-patterns**
|
|
174
|
+
- MEDIUM: Missing `@ngjit` on nested for-loops over `.data` arrays
|
|
175
|
+
- MEDIUM: `@jit` without `nopython=True`
|
|
176
|
+
- LOW: Type instability — initializing with int then assigning float
|
|
177
|
+
- LOW: Column-major iteration on row-major arrays (inner loop should be
|
|
178
|
+
last axis)
|
|
179
|
+
|
|
180
|
+
**Cat 6 — 30TB / 16GB OOM verdict**
|
|
181
|
+
For each dask code path, follow it end-to-end. Decide whether peak memory
|
|
182
|
+
scales with chunk size or with the full array. Optionally write a small
|
|
183
|
+
script under `/tmp/` (with a unique name including the module name) that
|
|
184
|
+
constructs the dask task graph and reports task count and fan-in:
|
|
185
|
+
|
|
186
|
+
```python
|
|
187
|
+
import dask.array as da
|
|
188
|
+
import xarray as xr
|
|
189
|
+
import json
|
|
190
|
+
|
|
191
|
+
arr = da.zeros((2560, 2560), chunks=(256, 256), dtype='float64')
|
|
192
|
+
raster = xr.DataArray(arr, dims=['y', 'x'])
|
|
193
|
+
# add coords if needed
|
|
194
|
+
try:
|
|
195
|
+
result = MODULE_FUNCTION(raster, **DEFAULT_ARGS)
|
|
196
|
+
graph = result.__dask_graph__()
|
|
197
|
+
task_count = len(graph)
|
|
198
|
+
print(json.dumps({
|
|
199
|
+
"success": True,
|
|
200
|
+
"task_count": task_count,
|
|
201
|
+
"tasks_per_chunk": round(task_count / 100.0, 2),
|
|
202
|
+
}))
|
|
203
|
+
except Exception as e:
|
|
204
|
+
print(json.dumps({"success": False, "error": str(e)}))
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
The script must NEVER call `.compute()` — graph construction only.
|
|
208
|
+
|
|
209
|
+
Verdict: one of `SAFE`, `RISKY`, `WILL OOM`, or `N/A` (no dask backend).
|
|
210
|
+
|
|
211
|
+
3. Classify the module's bottleneck as ONE of:
|
|
212
|
+
`IO-bound`, `memory-bound`, `compute-bound`, `graph-bound`.
|
|
213
|
+
|
|
214
|
+
4. For each real issue found, assign a severity (CRITICAL/HIGH/MEDIUM/LOW)
|
|
215
|
+
and note the exact file and line number.
|
|
216
|
+
|
|
217
|
+
5. If any CRITICAL or HIGH issue is found, run /rockout to fix it end-to-end
|
|
218
|
+
(GitHub issue, worktree branch, fix, tests, and PR). Include the OOM
|
|
219
|
+
verdict, bottleneck classification, and affected backends in the rockout
|
|
220
|
+
prompt so it has full performance context.
|
|
221
|
+
|
|
222
|
+
Skip step 5 entirely if `--no-fix` was passed to the parent sweep.
|
|
223
|
+
|
|
224
|
+
6. After finishing (whether you found issues or not), update the inspection
|
|
225
|
+
state file `.claude/sweep-performance-state.csv`. Header:
|
|
226
|
+
|
|
227
|
+
`module,last_inspected,oom_verdict,bottleneck,high_count,issue,notes`
|
|
228
|
+
|
|
229
|
+
Use this Python pattern to read, update, and write it (do NOT hand-edit
|
|
230
|
+
the file -- always go through csv.DictReader / csv.DictWriter so quoting
|
|
231
|
+
stays consistent):
|
|
232
|
+
|
|
233
|
+
```python
|
|
234
|
+
import csv
|
|
235
|
+
from pathlib import Path
|
|
236
|
+
|
|
237
|
+
path = Path(".claude/sweep-performance-state.csv")
|
|
238
|
+
header = ["module", "last_inspected", "oom_verdict", "bottleneck",
|
|
239
|
+
"high_count", "issue", "notes"]
|
|
240
|
+
|
|
241
|
+
rows = {}
|
|
242
|
+
if path.exists():
|
|
243
|
+
with path.open() as f:
|
|
244
|
+
for r in csv.DictReader(f):
|
|
245
|
+
rows[r["module"]] = r # last write wins on dupes
|
|
246
|
+
|
|
247
|
+
rows["{module}"] = {
|
|
248
|
+
"module": "{module}",
|
|
249
|
+
"last_inspected": "<today's ISO date, e.g. 2026-04-29>",
|
|
250
|
+
"oom_verdict": "<SAFE|RISKY|WILL OOM|N/A>",
|
|
251
|
+
"bottleneck": "<IO-bound|memory-bound|compute-bound|graph-bound>",
|
|
252
|
+
"high_count": "<integer, count of HIGH findings>",
|
|
253
|
+
"issue": "<issue number from rockout, or empty string>",
|
|
254
|
+
"notes": "<single-line notes (replace any newlines with spaces), or empty>",
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
with path.open("w", newline="") as f:
|
|
258
|
+
w = csv.DictWriter(f, fieldnames=header, quoting=csv.QUOTE_MINIMAL)
|
|
259
|
+
w.writeheader()
|
|
260
|
+
for m in sorted(rows):
|
|
261
|
+
w.writerow(rows[m])
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Use empty strings (not `null`) for missing values. Set `issue` to the
|
|
265
|
+
issue number when one was filed, otherwise leave it empty.
|
|
266
|
+
|
|
267
|
+
Then `git add .claude/sweep-performance-state.csv` and commit it to the
|
|
268
|
+
worktree branch so the state update is included in the PR.
|
|
269
|
+
|
|
270
|
+
Important:
|
|
271
|
+
- Only flag patterns ACTUALLY present in the code. False positives are worse
|
|
272
|
+
than missed issues.
|
|
273
|
+
- Read the tests for this module before flagging a pattern as harmful — the
|
|
274
|
+
test may codify the current behavior intentionally.
|
|
275
|
+
- For CUDA code, verify register pressure and bounds before flagging.
|
|
276
|
+
- Do NOT flag the use of numba @jit itself as a performance issue. Focus on
|
|
277
|
+
what the JIT code does, not that it uses JIT.
|
|
278
|
+
- For the hydro subpackage: focus on one representative variant (d8) in
|
|
279
|
+
detail, then note which dinf/mfd files share the same pattern. Do not read
|
|
280
|
+
all 29 files line by line.
|
|
281
|
+
- This repo uses ArrayTypeFunctionMapping to dispatch across numpy/cupy/dask
|
|
282
|
+
backends. Check all backend paths, not just numpy.
|
|
283
|
+
- Do NOT call `.compute()` in any analysis script. Graph construction only.
|
|
284
|
+
~~~
|
|
285
|
+
|
|
286
|
+
### 3c. Print a status line
|
|
287
|
+
|
|
288
|
+
After dispatching, print:
|
|
289
|
+
|
|
290
|
+
```
|
|
291
|
+
Launched {N} performance audit agents: {module1}, {module2}, {module3}
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
## Step 4 -- State updates
|
|
295
|
+
|
|
296
|
+
State is updated by the subagents themselves (see agent prompt step 6).
|
|
297
|
+
After completion, verify state with:
|
|
298
|
+
|
|
299
|
+
```
|
|
300
|
+
column -t -s, .claude/sweep-performance-state.csv | less
|
|
301
|
+
```
|
|
302
|
+
|
|
303
|
+
To reset all tracking: `/sweep-performance --reset-state`
|
|
304
|
+
|
|
305
|
+
---
|
|
306
|
+
|
|
307
|
+
## General Rules
|
|
308
|
+
|
|
309
|
+
- Do NOT modify any source files from the parent. Subagents handle fixes via
|
|
310
|
+
/rockout.
|
|
311
|
+
- Keep the parent output concise — the ranked table and dispatch line are
|
|
312
|
+
the deliverables.
|
|
313
|
+
- If $ARGUMENTS is empty, use defaults: top 3, no category filter, no
|
|
314
|
+
exclusions.
|
|
315
|
+
- State file (`.claude/sweep-performance-state.csv`) is tracked in git, with
|
|
316
|
+
`merge=union` set in `.gitattributes` so parallel sweeps touching
|
|
317
|
+
different modules auto-merge. Subagents must `git add` and commit it so
|
|
318
|
+
the state update lands in the PR.
|
|
319
|
+
- For subpackage modules (geotiff, reproject, hydro), the subagent reads ALL
|
|
320
|
+
`.py` files in the subpackage directory, not just `__init__.py`.
|
|
321
|
+
- Only flag patterns that are ACTUALLY present in the code. Do not report
|
|
322
|
+
hypothetical issues or patterns that "could" occur with imaginary inputs.
|
|
323
|
+
- False positives are worse than missed issues. When in doubt, skip.
|
|
324
|
+
- The 30TB graph simulation NEVER calls `.compute()` — it constructs the
|
|
325
|
+
dask graph and inspects it.
|