Skip to content

Commit

Permalink
Expose cython API for external use (#234)
Browse files Browse the repository at this point in the history
* Expose cython API for internal use

* fix typeo

* Expose Cython API for external use

* Add Cython test

* Install cython in tests

* fix syntax for 2.7 and 3.5

* Fix lint check

* Call pytest on directory

* Build cython test in coverage-lint

* Only run cython test if import succeeds

* No bare except
  • Loading branch information
kylebarron authored May 13, 2022
1 parent 3d09da1 commit f59a1ea
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 3 deletions.
5 changes: 4 additions & 1 deletion .github/workflows/coverage-lint.yml
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,10 @@ jobs:
run: pylint --disable=all --enable=import-error tests/

- name: Coverage
run: pytest --cov=h3 --full-trace --cov-report=xml
run: |
pip install Cython
cythonize -i tests/cython_example.pyx
pytest --cov=h3 --full-trace --cov-report=xml
- name: Upload coverage to Codecov
uses: codecov/[email protected]
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,4 +47,7 @@ jobs:
pip install .[all]
- name: Tests
run: pytest --cov=h3 --full-trace
run: |
pip install Cython
cythonize -i tests/cython_example.pyx
pytest tests --cov=h3 --full-trace
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ h3c/
.cache/
h3/out/

# Generated C code from Cython test
tests/*.c
# Cython HTML annotations
*.html

Expand Down
7 changes: 7 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,10 @@ add_subdirectory(src/h3lib)
# Build the rest (other than the core library dependency) as shared
set(BUILD_SHARED_LIBS ON)
add_subdirectory(src/h3)

# Include built h3api.h for Cython API
install(
FILES
"${CMAKE_CURRENT_BINARY_DIR}/src/h3lib/src/h3lib/include/h3api.h"
DESTINATION
src/h3/_cy)
3 changes: 2 additions & 1 deletion makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,8 @@ annotations: rebuild
cp _skbuild/*/cmake-build/src/h3/_cy/*.html ./annotations

test:
env/bin/pytest tests/* --cov=h3 --cov-report term-missing --durations=10
env/bin/cythonize -i tests/cython_example.pyx
env/bin/pytest tests --cov=h3 --cov-report term-missing --durations=10

lint:
env/bin/flake8 src/h3 setup.py tests
Expand Down
16 changes: 16 additions & 0 deletions src/h3/_cy/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,19 @@ add_cython_file(cells)
add_cython_file(edges)
add_cython_file(to_multipoly)
add_cython_file(unstable_vect)

# Include pyx and pxd files in distribution for use by Cython API
install(
FILES
cells.pxd
cells.pyx
edges.pxd
edges.pyx
geo.pxd
geo.pyx
h3lib.pxd
util.pxd
util.pyx
DESTINATION
src/h3/_cy
)
Empty file added tests/__init__.py
Empty file.
18 changes: 18 additions & 0 deletions tests/cython_example.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from cython cimport boundscheck, wraparound

from h3._cy.h3lib cimport H3int
from h3._cy.geo cimport geo_to_h3

@boundscheck(False)
@wraparound(False)
cpdef void geo_to_h3_vect(
const double[:] lat,
const double[:] lng,
int res,
H3int[:] out
):

cdef Py_ssize_t i

for i in range(len(lat)):
out[i] = geo_to_h3(lat[i], lng[i], res)
28 changes: 28 additions & 0 deletions tests/test_cython.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import numpy as np

# Avoid checking for import-error here because cython_example may not have
# been compiled yet.
try:
from .cython_example import geo_to_h3_vect # pylint: disable=import-error
except ImportError:
geo_to_h3_vect = None

np.random.seed(0)


def test_cython_api():
if geo_to_h3_vect is None:
print("Not running Cython test because cython example was not compiled")
return

N = 100000

lats, lngs = np.random.uniform(0, 90, N), np.random.uniform(0, 90, N)
res = 9

lats = np.array(lats, dtype=np.float64)
lngs = np.array(lngs, dtype=np.float64)
out = np.zeros(len(lats), dtype="uint64")
geo_to_h3_vect(lats, lngs, res, out)

assert out[0] == 617284541015654399

0 comments on commit f59a1ea

Please sign in to comment.