Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

C++ pairwise linestring distance #510

Merged
merged 77 commits into from
May 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
77 commits
Select commit Hold shift + click to select a range
0f2c62c
Initial pass of linestring distance and test
isVoid Mar 31, 2022
29f1d62
Add more one pair linestring tests
isVoid Mar 31, 2022
954bbfc
More single pair testing
isVoid Apr 1, 2022
03748ea
update docstring
isVoid Apr 1, 2022
3b52203
Add medium test
isVoid Apr 7, 2022
6deb261
Wrapping debug prints
isVoid Apr 7, 2022
61716c6
Initial
isVoid Apr 7, 2022
95a803f
Merge branch 'fea/enable_nvbench' into feature/linestring_distance
isVoid Apr 7, 2022
3375b1b
Merge branch 'branch-22.06' of github.com:rapidsai/cuspatial into fea…
isVoid Apr 7, 2022
3cab72d
initial
isVoid Apr 7, 2022
1c6322e
Merge branch 'fix/update_cuda_try' into feature/linestring_distance_b…
isVoid Apr 7, 2022
f6b571a
Update synchonization.cpp
isVoid Apr 7, 2022
2c3a038
Merge branch 'fix/update_cuda_try' into fea/enable_nvbench
isVoid Apr 8, 2022
90de8ce
Replace one more usage of `CUDF_CUDA_TRY`
isVoid Apr 8, 2022
3efb6b0
Merge branch 'fix/update_cuda_try' into feature/linestring_distance_b…
isVoid Apr 8, 2022
a637664
Merge branch 'fea/enable_nvbench' into feature/linestring_distance_be…
isVoid Apr 8, 2022
d82f887
Add nvbench cpm
isVoid Apr 8, 2022
80e2d27
Merge branch 'fea/enable_nvbench' into feature/linestring_distance_be…
isVoid Apr 8, 2022
813178c
Add runnable nvbench
isVoid Apr 8, 2022
aa65c75
Add data gen synchronizer
isVoid Apr 8, 2022
511dd5d
Rewrites kernel to schedule on num points
isVoid Apr 9, 2022
cee2c1f
Change problem size in benchmarks
isVoid Apr 9, 2022
3bf3d44
In the middle of getting the compiler to include the file.
isVoid Apr 14, 2022
2006ac1
passes compilation
isVoid Apr 14, 2022
f463bd8
Revert "passes compilation"
isVoid Apr 14, 2022
08ef028
Revert "In the middle of getting the compiler to include the file."
isVoid Apr 14, 2022
53e822a
Code cleanups and completes docstrings
isVoid Apr 14, 2022
5dd6a4c
Revert "Change problem size in benchmarks"
isVoid Apr 14, 2022
2b1da4a
Revert "Add data gen synchronizer"
isVoid Apr 14, 2022
d8e6902
Revert "Add runnable nvbench"
isVoid Apr 14, 2022
2341301
Revert "Add nvbench cpm"
isVoid Apr 14, 2022
cc6f1a2
Revert benchmark cmake introduction of nvbench.
isVoid Apr 14, 2022
daa2966
Merge branch 'branch-22.06' of https://github.com/rapidsai/cuspatial …
isVoid Apr 14, 2022
decac94
Add small helper to retrieve endpoint index.
isVoid Apr 14, 2022
0f139e0
More cleanups
isVoid Apr 14, 2022
30ac95c
Add single test sample from geolife
isVoid Apr 25, 2022
53a4135
Fix typo
isVoid Apr 25, 2022
b606956
Fix bug where collinear line segments are taken as intersect segments
isVoid Apr 26, 2022
6811cb6
Add test case for various collinear line segments and an geolife example
isVoid Apr 26, 2022
90a5102
Multiple update with docstrings.
isVoid Apr 27, 2022
77b27a9
style fix
isVoid Apr 27, 2022
468a5e9
Switch to snake case.
isVoid Apr 27, 2022
c5df642
fix typo
isVoid Apr 27, 2022
777a01a
Rename coord_2d to vec_2d. Add vec_2d operators, rewrites `point_to_s…
isVoid Apr 28, 2022
aa93829
Merge master from upstream
isVoid Apr 28, 2022
e0a15d8
Migrate vec2d operators to vec_2d.cuh
isVoid Apr 28, 2022
877d74e
Add docstrings for operators
isVoid Apr 28, 2022
2a58b0e
Add macro for portable host_device code
isVoid Apr 28, 2022
6fdd25a
Revert "Merge master from upstream"
isVoid Apr 28, 2022
9fa8136
Add macro for portable host-device operators
isVoid Apr 28, 2022
39baadf
Merge branch 'branch-22.06' of https://github.com/rapidsai/cuspatial …
isVoid Apr 28, 2022
cc0f526
Optimize `segment_distance` method
isVoid Apr 28, 2022
f55db25
Avoid using `double` for tempeoraries
isVoid Apr 28, 2022
22ed7ec
Remove vec2d elementwise add
isVoid Apr 28, 2022
a477f2b
remove validation
isVoid Apr 28, 2022
708906d
Add aka polylines
isVoid Apr 28, 2022
2dc421b
Add examples in docstring and test for it
isVoid Apr 28, 2022
497f1d1
update docstring of `det`
isVoid Apr 28, 2022
c09689a
Add denormalized determinants test
isVoid Apr 29, 2022
7023faa
adopt almost always auto
isVoid May 2, 2022
8004ec9
doc updates
isVoid May 2, 2022
654c08b
Several docstring updates
isVoid May 3, 2022
c864dca
update colinear names
isVoid May 3, 2022
ddf497e
fix typo
isVoid May 3, 2022
1203a86
Merge branch 'feature/linestring_distance' of github.com:isVoid/cuspa…
isVoid May 3, 2022
2da3a66
Template out the sizetype
isVoid May 3, 2022
338a5ad
Move 2d vector type definitions to `vec_2d.hpp`
isVoid May 3, 2022
94b78f3
Include vector types in haversine method
isVoid May 3, 2022
a3e84ee
update example and test
isVoid May 4, 2022
c40b81f
Lift sqrt outside of the segment distance.
isVoid May 5, 2022
65a835c
Update docstring LRAI links.
isVoid May 5, 2022
23875ee
Replace type declaration with `auto`
isVoid May 5, 2022
ac53f8d
Delay computations
isVoid May 5, 2022
b546e7a
Use constexpr for `tpb`
isVoid May 5, 2022
26fa8d4
Replace division with multiply denom reciprocals
isVoid May 5, 2022
b7dda2c
delay computing `bc`
isVoid May 5, 2022
2c60a5d
docstring fixes
isVoid May 5, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions cpp/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,7 @@ add_library(cuspatial
src/spatial_window/spatial_window.cu
src/spatial/haversine.cu
src/spatial/hausdorff.cu
src/spatial/linestring_distance.cu
src/spatial/lonlat_to_cartesian.cu
src/trajectory/derive_trajectories.cu
src/trajectory/trajectory_bounding_boxes.cu
Expand Down
109 changes: 109 additions & 0 deletions cpp/include/cuspatial/distances/linestring_distance.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright (c) 2022, NVIDIA CORPORATION.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

#pragma once

#include <cudf/column/column_view.hpp>
#include <cudf/utilities/span.hpp>

#include <memory>

namespace cuspatial {

/**
* @brief Compute shortest distance between pairs of linestrings (a.k.a. polylines)
*
* The shortest distance between two linestrings is defined as the shortest distance
* between all pairs of segments of the two linestrings. If any of the segments intersect,
* the distance is 0.
isVoid marked this conversation as resolved.
Show resolved Hide resolved
*
* The following example contains 4 pairs of linestrings.
*
* First pair:
* (0, 1) -> (1, 0) -> (-1, 0)
* (1, 1) -> (2, 1) -> (2, 0) -> (3, 0)
*
* |
* * #---#
* | \ |
* ----O---*---#---#
* | /
* *
* |
*
* The shortest distance between the two linestrings is the distance
* from point (1, 1) to segment (0, 1) -> (1, 0), which is sqrt(2)/2.
*
* Second pair:
*
* (0, 0) -> (0, 1)
* (1, 0) -> (1, 1) -> (1, 2)
*
* These linestrings are parallel. Their distance is 1 (point (0, 0) to point (1, 0)).
*
* Third pair:
*
* (0, 0) -> (2, 2) -> (-2, 0)
* (2, 0) -> (0, 2)
*
* These linestrings intersect, so their distance is 0.
*
* Forth pair:
*
* (2, 2) -> (-2, -2)
* (1, 1) -> (5, 5) -> (10, 0)
*
* These linestrings contain colinear and overlapping sections, so
* their distance is 0.
*
* The input of above example is:
* linestring1_offsets: {0, 3, 5, 8}
* linestring1_points_x: {0, 1, -1, 0, 0, 0, 2, -2, 2, -2}
* linestring1_points_y: {1, 0, 0, 0, 1, 0, 2, 0, 2, -2}
* linestring2_offsets: {0, 4, 7, 9}
* linestring2_points_x: {1, 2, 2, 3, 1, 1, 1, 2, 0, 1, 5, 10}
* linestring2_points_y: {1, 1, 0, 0, 0, 1, 2, 0, 2, 1, 5, 0}
*
* Result: {sqrt(2.0)/2, 1, 0, 0}
*
* @param linestring1_offsets Indices of the first point of the first linestring of each pair.
* @param linestring1_points_x x-components of points in the first linestring of each pair.
* @param linestring1_points_y y-component of points in the first linestring of each pair.
* @param linestring2_offsets Indices of the first point of the second linestring of each pair.
* @param linestring2_points_x x-component of points in the first linestring of each pair.
* @param linestring2_points_y y-component of points in the first linestring of each pair.
* @param mr Device memory resource used to allocate the returned column's device memory.
* @return A column of shortest distances between each pair of linestrings.
*
* @note If any of the linestring contains less than 2 points, the behavior is undefined.
*
* @throw cuspatial::logic_error if `linestring1_offsets.size() != linestring2_offsets.size()`
* @throw cuspatial::logic_error if there is a size mismatch between the x- and y-coordinates of the
* linestring points.
* @throw cuspatial::logic_error if any of the point arrays have mismatched types.
* @throw cuspatial::logic_error if any linestring has fewer than 2 points.
*
*/
std::unique_ptr<cudf::column> pairwise_linestring_distance(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For discussion: Could/should the linestring1_points_x and linestring2_points_x be combined into a single array of x-coordinates? This would simplify the interface, but what I'm wondering is whether this would be easier or harder for users?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The limit is that the largest number of points both set can have in total is less than std::numeric_limit<size_type>::max(). This is more restrictive than having separate set of point vectors.
cc. @zhangjianting with usage question.

cudf::device_span<cudf::size_type const> linestring1_offsets,
cudf::column_view const& linestring1_points_x,
cudf::column_view const& linestring1_points_y,
cudf::device_span<cudf::size_type const> linestring2_offsets,
cudf::column_view const& linestring2_points_x,
cudf::column_view const& linestring2_points_y,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource());

} // namespace cuspatial
1 change: 1 addition & 0 deletions cpp/include/cuspatial/experimental/detail/haversine.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#include <cuspatial/constants.hpp>
#include <cuspatial/error.hpp>
#include <cuspatial/types.hpp>
#include <cuspatial/utility/vec_2d.hpp>

#include <rmm/cuda_stream_view.hpp>
#include <rmm/exec_policy.hpp>
Expand Down
30 changes: 6 additions & 24 deletions cpp/include/cuspatial/types.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,31 +18,13 @@

#include <cstdint>

namespace cuspatial {
#ifdef __CUDACC__
#define CUSPATIAL_HOST_DEVICE __host__ __device__
#else
#define CUSPATIAL_HOST_DEVICE
#endif

/**
* @brief A 2D vector
*
* Used in cuspatial for both Longitude/Latitude (LonLat) coordinate pairs and Cartesian (X/Y)
* coordinate pairs. For LonLat pairs, the `x` member represents Longitude, and `y` represents
* Latitude.
*
* @tparam T the base type for the coordinates
*/
template <typename T>
struct alignas(2 * sizeof(T)) vec_2d {
using value_type = T;
value_type x;
value_type y;
};

template <typename T>
struct alignas(2 * sizeof(T)) lonlat_2d : vec_2d<T> {
};

template <typename T>
struct alignas(2 * sizeof(T)) cartesian_2d : vec_2d<T> {
};
namespace cuspatial {

/**
* @brief A timestamp
Expand Down
84 changes: 84 additions & 0 deletions cpp/include/cuspatial/utility/vec_2d.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
#pragma once
#include <cuspatial/types.hpp>

namespace cuspatial {

/**
* @brief A 2D vector
*
* Used in cuspatial for both Longitude/Latitude (LonLat) coordinate pairs and Cartesian (X/Y)
* coordinate pairs. For LonLat pairs, the `x` member represents Longitude, and `y` represents
* Latitude.
*
* @tparam T the base type for the coordinates
*/
template <typename T>
struct alignas(2 * sizeof(T)) vec_2d {
using value_type = T;
value_type x;
value_type y;
};

template <typename T>
struct alignas(2 * sizeof(T)) lonlat_2d : vec_2d<T> {
};

template <typename T>
struct alignas(2 * sizeof(T)) cartesian_2d : vec_2d<T> {
};

/**
* @brief Element-wise add of two 2d vectors.
*/
template <typename T>
vec_2d<T> CUSPATIAL_HOST_DEVICE operator+(vec_2d<T> const& a, vec_2d<T> const& b)
{
return vec_2d<T>{a.x + b.x, a.y + b.y};
}

/**
* @brief Element-wise subtract of two 2d vectors.
*/
template <typename T>
vec_2d<T> CUSPATIAL_HOST_DEVICE operator-(vec_2d<T> const& a, vec_2d<T> const& b)
{
return vec_2d<T>{a.x - b.x, a.y - b.y};
}

/**
* @brief Scale a 2d vector by ratio @p r.
*/
template <typename T>
vec_2d<T> CUSPATIAL_HOST_DEVICE operator*(vec_2d<T> vec, T const& r)
{
return vec_2d<T>{vec.x * r, vec.y * r};
}

/**
* @brief Scale a 2d vector by ratio @p r.
*/
template <typename T>
vec_2d<T> CUSPATIAL_HOST_DEVICE operator*(T const& r, vec_2d<T> vec)
{
return vec * r;
}

/**
* @brief Compute dot product of two 2d vectors.
*/
template <typename T>
T CUSPATIAL_HOST_DEVICE dot(vec_2d<T> const& a, vec_2d<T> const& b)
{
return a.x * b.x + a.y * b.y;
}

/**
* @brief Compute 2d determinant of a 2x2 matrix with column vectors @p a and @p b.
*/
template <typename T>
T CUSPATIAL_HOST_DEVICE det(vec_2d<T> const& a, vec_2d<T> const& b)
{
return a.x * b.y - a.y * b.x;
}

} // namespace cuspatial
Loading