Skip to content

Commit

Permalink
Add python bindings for (multi)point-(multi)point distance (#734)
Browse files Browse the repository at this point in the history
This PR adds python bindings to Point-point distance. Depend on #731 
Reverts change to comment: #731 (comment)

Close #578

Authors:
  - Michael Wang (https://github.com/isVoid)

Approvers:
  - Mark Harris (https://github.com/harrism)
  - H. Thomson Comer (https://github.com/thomcom)

URL: #734
  • Loading branch information
isVoid committed Oct 25, 2022
1 parent 3774543 commit cf5117b
Show file tree
Hide file tree
Showing 12 changed files with 314 additions and 119 deletions.
4 changes: 2 additions & 2 deletions cpp/include/cuspatial/distance/point_distance.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,10 @@ namespace cuspatial {
*/

std::unique_ptr<cudf::column> pairwise_point_distance(
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points2_xy,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,
cudf::column_view const& points2_xy,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource());

} // namespace cuspatial
20 changes: 10 additions & 10 deletions cpp/src/spatial/point_distance.cu
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,10 @@ struct pairwise_point_distance_impl {
template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, std::unique_ptr<cudf::column>> operator()(
cudf::size_type num_pairs,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points2_xy,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,
cudf::column_view const& points2_xy,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr)
{
Expand Down Expand Up @@ -81,10 +81,10 @@ struct pairwise_point_distance_impl {
template <bool is_multipoint1, bool is_multipoint2>
struct pairwise_point_distance_functor {
std::unique_ptr<cudf::column> operator()(
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points2_xy,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,
cudf::column_view const& points2_xy,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr)
{
Expand All @@ -105,10 +105,10 @@ struct pairwise_point_distance_functor {
return cudf::type_dispatcher(points1_xy.type(),
pairwise_point_distance_impl<is_multipoint1, is_multipoint2>{},
num_lhs,
points1_xy,
multipoints1_offset,
points2_xy,
points1_xy,
multipoints2_offset,
points2_xy,
stream,
mr);
}
Expand All @@ -117,19 +117,19 @@ struct pairwise_point_distance_functor {
} // namespace detail

std::unique_ptr<cudf::column> pairwise_point_distance(
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints1_offset,
cudf::column_view const& points2_xy,
cudf::column_view const& points1_xy,
std::optional<cudf::device_span<cudf::size_type const>> multipoints2_offset,
cudf::column_view const& points2_xy,
rmm::mr::device_memory_resource* mr)
{
return double_boolean_dispatch<detail::pairwise_point_distance_functor>(
multipoints1_offset.has_value(),
multipoints2_offset.has_value(),
points1_xy,
multipoints1_offset,
points2_xy,
points1_xy,
multipoints2_offset,
points2_xy,
rmm::cuda_stream_default,
mr);
}
Expand Down
14 changes: 7 additions & 7 deletions cpp/tests/spatial/point_distance_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ TYPED_TEST(PairwisePointDistanceTest, SingleToSingleEmpty)

auto expect = fixed_width_column_wrapper<T>{};

auto got = pairwise_point_distance(xy1, offset1, xy2, offset2);
auto got = pairwise_point_distance(offset1, xy1, offset2, xy2);

CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got);
}
Expand All @@ -66,7 +66,7 @@ TYPED_TEST(PairwisePointDistanceTest, SingleToMultiEmpty)

auto expect = fixed_width_column_wrapper<T>{};

auto got = pairwise_point_distance(xy1, offset1, xy2, offset2);
auto got = pairwise_point_distance(offset1, xy1, offset2, xy2);

CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got);
}
Expand All @@ -83,7 +83,7 @@ TYPED_TEST(PairwisePointDistanceTest, MultiToSingleEmpty)

auto expect = fixed_width_column_wrapper<T>{};

auto got = pairwise_point_distance(xy1, offset1, xy2, offset2);
auto got = pairwise_point_distance(offset1, xy1, offset2, xy2);

CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got);
}
Expand All @@ -100,7 +100,7 @@ TYPED_TEST(PairwisePointDistanceTest, MultiToMultiEmpty)

auto expect = fixed_width_column_wrapper<T>{};

auto got = pairwise_point_distance(xy1, offset1, xy2, offset2);
auto got = pairwise_point_distance(offset1, xy1, offset2, xy2);

CUDF_TEST_EXPECT_COLUMNS_EQUIVALENT(expect, *got);
}
Expand All @@ -116,7 +116,7 @@ TEST_F(PairwisePointDistanceTestThrow, SizeMismatch)
auto xy1 = fixed_width_column_wrapper<float>{1, 1, 2, 2, 3, 3};
auto xy2 = fixed_width_column_wrapper<float>{};

EXPECT_THROW(pairwise_point_distance(xy1, offset1, xy2, offset2), cuspatial::logic_error);
EXPECT_THROW(pairwise_point_distance(offset1, xy1, offset2, xy2), cuspatial::logic_error);
}

TEST_F(PairwisePointDistanceTestThrow, SizeMismatch2)
Expand All @@ -127,7 +127,7 @@ TEST_F(PairwisePointDistanceTestThrow, SizeMismatch2)
auto xy1 = fixed_width_column_wrapper<float>{1, 1, 2, 2, 3, 3};
auto xy2 = fixed_width_column_wrapper<float>{};

EXPECT_THROW(pairwise_point_distance(xy1, offset1, xy2, offset2), cuspatial::logic_error);
EXPECT_THROW(pairwise_point_distance(offset1, xy1, offset2, xy2), cuspatial::logic_error);
}

TEST_F(PairwisePointDistanceTestThrow, TypeMismatch)
Expand All @@ -137,6 +137,6 @@ TEST_F(PairwisePointDistanceTestThrow, TypeMismatch)
auto xy1 = fixed_width_column_wrapper<float>{1, 1, 2, 2, 3, 3};
auto xy2 = fixed_width_column_wrapper<double>{1, 1, 2, 2, 3, 3};

EXPECT_THROW(pairwise_point_distance(xy1, offset1, xy2, offset2), cuspatial::logic_error);
EXPECT_THROW(pairwise_point_distance(offset1, xy1, offset2, xy2), cuspatial::logic_error);
}
} // namespace cuspatial
1 change: 1 addition & 0 deletions python/cuspatial/cuspatial/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
haversine_distance,
join_quadtree_and_bounding_boxes,
lonlat_to_cartesian,
pairwise_point_distance,
pairwise_linestring_distance,
pairwise_point_linestring_distance,
pairwise_point_linestring_nearest_points,
Expand Down
3 changes: 1 addition & 2 deletions python/cuspatial/cuspatial/_lib/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,13 @@
# =============================================================================

set(cython_sources
distance.pyx
hausdorff.pyx
interpolate.pyx
nearest_points.pyx
point_in_polygon.pyx
polygon_bounding_boxes.pyx
polyline_bounding_boxes.pyx
linestring_distance.pyx
point_linestring_distance.pyx
quadtree.pyx
shapefile_reader.pyx
spatial.pyx
Expand Down
20 changes: 20 additions & 0 deletions python/cuspatial/cuspatial/_lib/cpp/distance/point_distance.pxd
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# Copyright (c) 2022, NVIDIA CORPORATION.

from libcpp.memory cimport unique_ptr

from cudf._lib.column cimport Column
from cudf._lib.cpp.column.column cimport column
from cudf._lib.cpp.column.column_view cimport column_view
from cudf._lib.cpp.types cimport size_type

from cuspatial._lib.cpp.optional cimport optional


cdef extern from "cuspatial/distance/point_distance.hpp" \
namespace "cuspatial" nogil:
cdef unique_ptr[column] pairwise_point_distance(
const optional[column_view] multipoint1_offsets,
const column_view point1_xy,
const optional[column_view] multipoint2_offsets,
const column_view point2_xy
) except +
102 changes: 102 additions & 0 deletions python/cuspatial/cuspatial/_lib/distance.pyx
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
from typing import Optional

from libcpp.memory cimport unique_ptr
from libcpp.utility cimport move

from cudf._lib.column cimport Column
from cudf._lib.cpp.column.column cimport column
from cudf._lib.cpp.column.column_view cimport column_view

from cuspatial._lib.cpp.distance.linestring_distance cimport (
pairwise_linestring_distance as c_pairwise_linestring_distance,
)
from cuspatial._lib.cpp.distance.point_distance cimport (
pairwise_point_distance as c_pairwise_point_distance,
)
from cuspatial._lib.cpp.distance.point_linestring_distance cimport (
pairwise_point_linestring_distance as c_pairwise_point_linestring_distance,
)
from cuspatial._lib.cpp.optional cimport nullopt, optional
from cuspatial._lib.utils cimport unwrap_pyoptcol


def pairwise_point_distance(
Column points1_xy,
Column points2_xy,
multipoint1_offsets=None,
multipoint2_offsets=None,
):
cdef optional[column_view] c_multipoints1_offset = unwrap_pyoptcol(
multipoint1_offsets)
cdef optional[column_view] c_multipoints2_offset = unwrap_pyoptcol(
multipoint2_offsets)

cdef column_view c_points1_xy = points1_xy.view()
cdef column_view c_points2_xy = points2_xy.view()
cdef unique_ptr[column] c_result

with nogil:
c_result = move(c_pairwise_point_distance(
c_multipoints1_offset,
c_points1_xy,
c_multipoints2_offset,
c_points2_xy,
))
return Column.from_unique_ptr(move(c_result))


def pairwise_linestring_distance(
Column linestring1_offsets,
Column linestring1_points_x,
Column linestring1_points_y,
Column linestring2_offsets,
Column linestring2_points_x,
Column linestring2_points_y
):
cdef column_view linestring1_offsets_view = linestring1_offsets.view()
cdef column_view linestring1_points_x_view = linestring1_points_x.view()
cdef column_view linestring1_points_y_view = linestring1_points_y.view()
cdef column_view linestring2_offsets_view = linestring2_offsets.view()
cdef column_view linestring2_points_x_view = linestring2_points_x.view()
cdef column_view linestring2_points_y_view = linestring2_points_y.view()

cdef unique_ptr[column] c_result
with nogil:
c_result = move(c_pairwise_linestring_distance(
linestring1_offsets_view,
linestring1_points_x_view,
linestring1_points_y_view,
linestring2_offsets_view,
linestring2_points_x_view,
linestring2_points_y_view
))

return Column.from_unique_ptr(move(c_result))


def pairwise_point_linestring_distance(
Column points_xy,
Column linestring_part_offsets,
Column linestring_points_xy,
multipoint_geometry_offset=None,
multilinestring_geometry_offset=None,
):
cdef optional[column_view] c_multipoint_parts_offset = unwrap_pyoptcol(
multipoint_geometry_offset)
cdef optional[column_view] c_multilinestring_parts_offset = (
unwrap_pyoptcol(multilinestring_geometry_offset))

cdef column_view c_points_xy = points_xy.view()
cdef column_view c_linestring_offsets = linestring_part_offsets.view()
cdef column_view c_linestring_points_xy = linestring_points_xy.view()
cdef unique_ptr[column] c_result

with nogil:
c_result = move(c_pairwise_point_linestring_distance(
c_multipoint_parts_offset,
c_points_xy,
c_multilinestring_parts_offset,
c_linestring_offsets,
c_linestring_points_xy,
))
return Column.from_unique_ptr(move(c_result))
39 changes: 0 additions & 39 deletions python/cuspatial/cuspatial/_lib/linestring_distance.pyx

This file was deleted.

42 changes: 0 additions & 42 deletions python/cuspatial/cuspatial/_lib/point_linestring_distance.pyx

This file was deleted.

2 changes: 2 additions & 0 deletions python/cuspatial/cuspatial/core/spatial/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from .distance import (
directed_hausdorff_distance,
haversine_distance,
pairwise_point_distance,
pairwise_linestring_distance,
pairwise_point_linestring_distance,
)
Expand All @@ -33,6 +34,7 @@
"haversine_distance",
"join_quadtree_and_bounding_boxes",
"lonlat_to_cartesian",
"pairwise_point_distance",
"pairwise_linestring_distance",
"pairwise_point_linestring_distance",
"pairwise_point_linestring_nearest_points",
Expand Down
Loading

0 comments on commit cf5117b

Please sign in to comment.