How to Contribute to cuSpatial#

cuSpatial is a part of the RAPIDS community. When contributing to cuSpatial, developers should follow the RAPIDS contribution guidelines. The RAPIDS documentation contributing section walks through the process of identifying an issue, submitting and merging a PR.

Directory structure and file naming#

The cuspatial package comprises several subpackages.

  • core contains the main components of cuspatial

  • io contains I/O functions for reading and writing external data objects

  • tests contains unit tests for cuspatial

  • utils contains utility functions

  • _lib contains Cython APIs that wrap the C++ libcuspatial backend.

library_design further discusses high-level library design of cuspatial.

Cython code#

The _lib folder contains all cython code. Each feature in libcuspatial exposed to cuspatial should have two Cython files:

  1. A pxd file declaring C++ APIs so that they may be used in Cython, and

  2. A pyx file containing Cython functions that wrap those C++ APIs so that they can be called from Python.

pyx files are organized under the root of _lib. pxd files are under _lib/cpp. pxd files should mirror the file hierarchy of cpp/include in libcuspatial.

For more information see the Cython layer design documentation.

Code style#

cuSpatial employs a number of linters to ensure consistent style across the code base, and manages them using pre-commit. Developers are strongly recommended to set up pre-commit prior to any development. The .pre-commit-config.yaml file at the root of the repo is the primary source of truth for linting.

To install pre-commit, install via conda/pip:

# conda
conda install -c conda-forge pre-commit
# pip
pip install pre-commit

Then run pre-commit hooks before committing code:

pre-commit run

Optionally, you may set up the pre-commit hooks to run automatically when you make a git commit. This can be done by running the following command in cuspatial repository:

pre-commit install

Now code linters and formatters will be run each time you commit changes.

You can skip these checks with git commit --no-verify or with the short version git commit -n.

Linter Details#

Specifically, cuSpatial uses the following tools:

  • flake8 checks for general code formatting compliance.

  • black is an automatic code formatter.

  • isort ensures imports are sorted consistently.

Linter config data is stored in a number of files. cuSpatial generally uses pyproject.toml over setup.cfg and avoids project-specific files (e.g. setup.cfg > python/cudf/setup.cfg). However, differences between tools and the different packages in the repo result in the following caveats:

  • flake8 has no plans to support pyproject.toml, so it must live in setup.cfg.

  • isort must be configured per project to set which project is the “first party” project.

Additionally, cuSpatial’s use of versioneer means that each project must have a setup.cfg. As a result, cuSpatial currently maintains both root and project-level pyproject.toml and setup.cfg files.

Writing tests#

Every new feature contributed to cuspatial should include unit tests. The unit test file should be added to the tests folder. In general, the tests folder mirrors the folder hierarchy of the cuspatial package. At the lowest level, each module expands into a folder that contains specific test files for features in the module.

cuSpatial uses pytest as the unit testing framework. conftest.py contains useful fixtures that can be shared across different test functions. Reusing these fixtures reduces redundancy in test code.

cuspatial compute APIs should strive to reach result parity with its host (CPU) equivalent. For GeoSeries and GeoDataFrame features, unit tests should compare results with corresponding geopandas functions.