Repository navigation
perf(engine,coordinates): vectorize Impact.impact_at_reg CSR reduction and points_to_raster boxes - #1350
Conversation
…n and points_to_raster boxes
peanutfun
left a comment
There was a problem hiding this comment.
@napattan Thank you for your contribution! Please provide Python scripts to verify your claims on the speedup. Please also use the provided pull request description template (https://github.com/CLIMADA-project/climada_python/blob/main/.github/pull_request_template.md) for a smoother review. Finally, you added a test that does not verify anything (new). Please revise before we can merge
| df_geom = gpd.GeoDataFrame( | ||
| {"value": df_val["value"]}, | ||
| geometry=gpd.points_from_xy( | ||
| df_val["longitude"], df_val["latitude"] | ||
| ), | ||
| crs=DEF_CRS, | ||
| ) | ||
| r_geom, _ = u_coord.points_to_raster( | ||
| df_geom, | ||
| val_names=["value"], | ||
| res=0.5, | ||
| raster_res=1.0, | ||
| ) | ||
| np.testing.assert_allclose(r_geom, r_data) | ||
|
|
There was a problem hiding this comment.
This test does not make any sense. df_geom contains the same data as df_val. Then you call points_to_raster as above and check against the previous result.
There was a problem hiding this comment.
Removed this redundant df_geom test block in the latest commit. Thank you for noticing.
|
Hi @peanutfun, thank you for taking the time to review. My background is in landscape architecture, and I have been trying on integrating computational workflow and spatial analysis into my landscape and urban fields. Also I have used AI aided in my coding workflow and I read CLIMADA's AI policy markdown now, I take full responsibility for every line of code in this PR. I am still very new to contributing in open-source projects, I truly apologize for missing description template, issuing very unclearly, and for redundant test. I have updated the PR description above using If you checked and think this is unhelpful, please feel free to close this issue. |
|
@napattan All good, I appreciate your frankness and I'll walk you through it. Thanks for providing the benchmark code. Could you simplify it by only including the end-to-end calculations with timings? The script does not have to provide the speedup, just the run time. Then one can simply switch between branches, re-run the script, and see the timings for the actual branch code. The speedup for |
Changes proposed in this PR:
Impact.impact_at_reginclimada/engine/impact.pyby replacing the per-region Python list comprehension ([self.imp_mat[:, np.where(agg_regions == reg)[0]].sum(1) for reg in agg_reg_unique]) withnp.unique(agg_regions, return_inverse=True)and a single CSR sparse indicator matrix multiplication(self.imp_mat @ reg_ind).toarray().points_to_rasterinclimada/util/coordinates.py(apply_box) by replacing row-wisedf_exp.apply(lambda r: ..., axis=1)(Point(...).buffer(res / 2).envelope) withshapely.box(lon - res / 2, lat - res / 2, lon + res / 2, lat + res / 2).df_geomtest block inclimada/util/test/test_coordinates.pyand replace the duplicated list-comprehension check inclimada/engine/test/test_impact.py(TestImpactReg.test_agg_regions) with direct per-event assertions againstself.imp.at_eventandself.imp.imp_mat.toarray().Benchmark Verification Script & Results
Below is a self-contained script comparing
developvs. this PR across all 4 rows of the benchmark table (Impact.impact_at_regend-to-end,points_to_rasterapply_boxwithlatitude/longitudecolumns,points_to_rasterapply_boxwithgeometrycolumn, and full end-to-endpoints_to_rasterincludingdf_poly.to_crsandrasterio.features.rasterize):Measured results (Python 3.13, NumPy 2.4, SciPy 1.17, Shapely 2.1, GeoPandas 1.1):
develop(median / mean ± std)#1350(median / mean ± std)Impact.impact_at_reg2,000events ×50,000exposures ×100regions, CSRdensity=0.005)138.23 ms(138.79 ± 5.89 ms)11.78 ms(12.08 ± 1.01 ms)11.7xpoints_to_raster(apply_box)20,000points,lat/loncolumns)510.35 ms(509.87 ± 13.36 ms)7.30 ms(7.47 ± 0.86 ms)69.9xpoints_to_raster(apply_box)20,000points,geometrycolumn)451.23 ms(447.10 ± 12.45 ms)10.28 ms(10.10 ± 1.87 ms)43.9xpoints_to_raster(full function)apply_box+to_crs+rasterio.features.rasterize,20,000points)1001.34 ms(1003.06 ± 21.27 ms)483.83 ms(482.17 ± 27.66 ms)2.1xThis PR fixes # (N/A — performance optimization)
PR Author Checklist
develop)PR Reviewer Checklist