From 545344b2f08eaff78ca833e36a7f63e1da7c95a1 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 28 Jun 2023 17:11:07 -0700 Subject: [PATCH 01/12] add long input test case --- .../linestring_intersection_large_test.cu | 30 +++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/cpp/tests/intersection/linestring_intersection_large_test.cu b/cpp/tests/intersection/linestring_intersection_large_test.cu index aed4c00f3..3f7ba4fcd 100644 --- a/cpp/tests/intersection/linestring_intersection_large_test.cu +++ b/cpp/tests/intersection/linestring_intersection_large_test.cu @@ -27,6 +27,7 @@ #include #include +#include #include template @@ -2025,3 +2026,32 @@ TYPED_TEST(LinestringIntersectionLargeTest, LongInput) CUSPATIAL_RUN_TEST( this->template verify_legal_result, multilinestrings1.range(), multilinestrings2.range()); } + +template +struct coordinate_functor { + cuspatial::vec_2d __device__ operator()(std::size_t i) + { + return cuspatial::vec_2d{i / T{2.0}, i / T{2.0}}; + } +}; + +TYPED_TEST(LinestringIntersectionLargeTest, LongInput_2) +{ + using P = cuspatial::vec_2d; + auto geometry_offset = cuspatial::test::make_device_vector({0, 1}); + auto part_offset = cuspatial::test::make_device_vector({0, 130}); + auto coordinates = rmm::device_uvector

(260, this->stream()); + + thrust::tabulate(rmm::exec_policy(this->stream()), + coordinates.begin(), + thrust::next(coordinates.begin(), 128), + coordinate_functor{}); + + coordinates.set_element(128, P{127.0, 0.0}, this->stream()); + coordinates.set_element(129, P{0.0, 0.0}, this->stream()); + + auto rng = cuspatial::make_multilinestring_range( + 1, geometry_offset.begin(), 1, part_offset.begin(), 130, coordinates.begin()); + + CUSPATIAL_RUN_TEST(this->template verify_legal_result, rng, rng); +} From cbd803fa64b20bacf511a5846b19e181e6ea6cb6 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Wed, 28 Jun 2023 21:16:51 -0700 Subject: [PATCH 02/12] sort the segments before merging --- .../detail/find/find_and_combine_segment.cuh | 44 ++++++++++++++++++- .../intersection/linestring_intersection.cuh | 12 +++++ ...inestring_intersection_with_duplicates.cuh | 12 +++++ cpp/include/cuspatial/geometry/segment.cuh | 11 +++++ .../linestring_intersection_large_test.cu | 2 +- 5 files changed, 78 insertions(+), 3 deletions(-) diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index b05e71b03..d6fa8d5ea 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -19,18 +19,20 @@ #include #include #include +#include #include #include -#include +#include namespace cuspatial { namespace detail { /** * @internal - * @brief Kernel to merge segments, naive n^2 algorithm. + * @brief Kernel to merge segments. Each thread works on a pair of segment spaces. + * naive n^2 algorithm. */ template void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, @@ -44,6 +46,9 @@ void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, merged_flag[i] = 0; } + // For each of the segment, loop over the rest of the segment in the space and see + // if it is mergeable with the current segment. + // Note that if the current segment is already merged. Skip checking. for (auto i = offsets[pair_idx]; i < offsets[pair_idx + 1] && merged_flag[i] != 1; i++) { for (auto j = i + 1; j < offsets[pair_idx + 1]; j++) { auto res = maybe_merge_segments(segments[i], segments[j]); @@ -57,6 +62,29 @@ void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, } } +template +struct segment_comparator { + bool __device__ operator()(thrust::tuple> const& lhs, + thrust::tuple> const& rhs) const + { + auto lhs_index = thrust::get<0>(lhs); + auto rhs_index = thrust::get<0>(rhs); + auto lhs_segment = thrust::get<1>(lhs); + auto rhs_segment = thrust::get<1>(rhs); + + // Compare space id + if (lhs_index == rhs_index) { + // Compare slope + if (lhs_segment.collinear(rhs_segment)) { + // Sort by the lower left point of the segment. + return lhs_segment.lower_left() < rhs_segment.lower_left(); + } + return lhs_segment.slope() < rhs_segment.slope(); + } + return lhs_index < rhs_index; + } +}; + /** * @internal * @brief For each pair of mergeable segment, overwrites the first segment with merged result, @@ -68,9 +96,21 @@ void find_and_combine_segment(OffsetRange offsets, OutputIt merged_flag, rmm::cuda_stream_view stream) { + using index_t = typename OffsetRange::value_type; + using T = typename SegmentRange::value_type::value_type; auto num_spaces = offsets.size() - 1; if (num_spaces == 0) return; + // Construct a key iterator using the offsets of the segment and the segment itself. + auto space_id_iter = make_geometry_id_iterator(offsets.begin(), offsets.end()); + auto space_id_segment_iter = thrust::make_zip_iterator(space_id_iter, segments.begin()); + + thrust::sort_by_key(rmm::exec_policy(stream), + space_id_segment_iter, + space_id_segment_iter + segments.size(), + segments.begin(), + segment_comparator{}); + auto [threads_per_block, num_blocks] = grid_1d(num_spaces); simple_find_and_combine_segments_kernel<<>>( offsets, segments, merged_flag); diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh index 796365bde..c6c6e60ee 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh @@ -237,13 +237,25 @@ linestring_intersection_result pairwise_linestring_intersection( points.remove_if(range(point_flags.begin(), point_flags.end()), stream); if (segments.num_geoms() > 0) { + segments.debug_print(); // Merge mergeable segments rmm::device_uvector segment_flags(num_segments, stream); detail::find_and_combine_segment( segments.offset_range(), segments.geom_range(), segment_flags.begin(), stream); + std::cout << "\n\n"; + rmm::device_uvector segment_flags_int(num_segments, stream); + thrust::copy(rmm::exec_policy(stream), + segment_flags.begin(), + segment_flags.end(), + segment_flags_int.begin()); + test::print_device_vector(segment_flags_int, "segment_flags"); + std::cout << "\n\n"; + segments.remove_if(range(segment_flags.begin(), segment_flags.end()), stream); + segments.debug_print(); + // Reusing `point_flags` for merge point on segment primitive. // Notice that `point_flags` contains leftovers from previous `find_duplicate_points` call. // Here it does not need to be zero initialized because find_points_on_segments will overwrite diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index 8e35dfdca..2af03db64 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -16,6 +16,8 @@ #pragma once +#include + #include #include #include @@ -361,6 +363,16 @@ struct linestring_intersection_intermediates { /// Return the number of geometries in the intermediates auto num_geoms() { return geoms->size(); } + + void debug_print() + { + test::print_device_vector(*offsets, "offsets: "); + test::print_device_vector(*geoms, "geoms: "); + test::print_device_vector(*lhs_linestring_ids, "lhs_linestring_ids: "); + test::print_device_vector(*lhs_segment_ids, "lhs_segment_ids: "); + test::print_device_vector(*rhs_linestring_ids, "rhs_linestring_ids: "); + test::print_device_vector(*rhs_segment_ids, "rhs_segment_ids: "); + } }; /** diff --git a/cpp/include/cuspatial/geometry/segment.cuh b/cpp/include/cuspatial/geometry/segment.cuh index 9cfaf3b8e..9788d789a 100644 --- a/cpp/include/cuspatial/geometry/segment.cuh +++ b/cpp/include/cuspatial/geometry/segment.cuh @@ -55,6 +55,17 @@ class alignas(sizeof(Vertex)) segment { /// Return the length squared of segment. T CUSPATIAL_HOST_DEVICE length2() const { return dot(v2 - v1, v2 - v1); } + /// Return slope of segment. + T CUSPATIAL_HOST_DEVICE slope() { return (v2.y - v1.y) / (v2.x - v1.x); } + + /// Return the lower left vertex of segment. + Vertex CUSPATIAL_HOST_DEVICE lower_left() { return v1 < v2 ? v1 : v2; } + + bool CUSPATIAL_HOST_DEVICE collinear(segment const& other) + { + return (v1.x - v1.y) * (other.v2.x - other.v2.y) == (v2.x - v2.y) * (other.v1.x - other.v1.y); + } + private: friend std::ostream& operator<<(std::ostream& os, segment const& seg) { diff --git a/cpp/tests/intersection/linestring_intersection_large_test.cu b/cpp/tests/intersection/linestring_intersection_large_test.cu index 3f7ba4fcd..85c221678 100644 --- a/cpp/tests/intersection/linestring_intersection_large_test.cu +++ b/cpp/tests/intersection/linestring_intersection_large_test.cu @@ -2031,7 +2031,7 @@ template struct coordinate_functor { cuspatial::vec_2d __device__ operator()(std::size_t i) { - return cuspatial::vec_2d{i / T{2.0}, i / T{2.0}}; + return cuspatial::vec_2d{static_cast(i), static_cast(i)}; } }; From 04d551e855ee54e7f14b0be777d5b2afd4fb89d6 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 11:58:58 -0700 Subject: [PATCH 03/12] add twospaces find and combine test --- .../find/find_and_combine_segments_test.cu | 22 +++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/cpp/tests/find/find_and_combine_segments_test.cu b/cpp/tests/find/find_and_combine_segments_test.cu index ea01d7e53..e388bae73 100644 --- a/cpp/tests/find/find_and_combine_segments_test.cu +++ b/cpp/tests/find/find_and_combine_segments_test.cu @@ -281,3 +281,25 @@ TYPED_TEST(FindAndCombineSegmentsTest, nooverlap3) {0, 0}, {S{P{0.0, 0.0}, P{1.0, 1.0}}, S{P{0.0, 1.0}, P{1.0, 0.0}}}); } + +TYPED_TEST(FindAndCombineSegmentsTest, twospaces) +{ + using T = TypeParam; + using index_t = std::size_t; + using P = vec_2d; + using S = segment; + + auto segments = make_segment_array({0, 2, 4}, + {S{P{0.0, 0.0}, P{1.0, 1.0}}, + S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{1.0, 1.0}, P{0.0, 0.0}}, + S{P{2.0, 2.0}, P{1.0, 1.0}}}); + + CUSPATIAL_RUN_TEST(this->run_single_test, + segments, + {0, 1, 0, 1}, + {S{P{0.0, 0.0}, P{2.0, 2.0}}, + S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{0.0, 0.0}, P{2.0, 2.0}}, + S{P{2.0, 2.0}, P{1.0, 1.0}}}); +} From bbc2dce2d502edc650697be7e551852f202a1ae5 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 12:18:23 -0700 Subject: [PATCH 04/12] add twospaces, non-contiguous input --- .../detail/find/find_and_combine_segment.cuh | 3 +++ .../find/find_and_combine_segments_test.cu | 22 +++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index d6fa8d5ea..1f436dbf0 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -16,6 +16,7 @@ #pragma once +#include "cuspatial_test/test_util.cuh" #include #include #include @@ -24,6 +25,8 @@ #include #include +#include + #include namespace cuspatial { diff --git a/cpp/tests/find/find_and_combine_segments_test.cu b/cpp/tests/find/find_and_combine_segments_test.cu index e388bae73..9905b53dd 100644 --- a/cpp/tests/find/find_and_combine_segments_test.cu +++ b/cpp/tests/find/find_and_combine_segments_test.cu @@ -303,3 +303,25 @@ TYPED_TEST(FindAndCombineSegmentsTest, twospaces) S{P{0.0, 0.0}, P{2.0, 2.0}}, S{P{2.0, 2.0}, P{1.0, 1.0}}}); } + +TYPED_TEST(FindAndCombineSegmentsTest, twospaces_non_contiguous_segments_with_empty) +{ + using T = TypeParam; + using index_t = std::size_t; + using P = vec_2d; + using S = segment; + + auto segments = make_segment_array({0, 4, 4}, + {S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{3.0, 3.0}, P{4.0, 4.0}}, + S{P{0.0, 0.0}, P{1.0, 1.0}}, + S{P{2.0, 2.0}, P{3.0, 3.0}}}); + + CUSPATIAL_RUN_TEST(this->run_single_test, + segments, + {0, 1, 1, 1}, + {S{P{0.0, 0.0}, P{4.0, 4.0}}, + S{P{1.0, 1.0}, P{2.0, 2.0}}, + S{P{2.0, 2.0}, P{3.0, 3.0}}, + S{P{3.0, 3.0}, P{4.0, 4.0}}}); +} From 83d19af4d2a2d1dcf1624d29dc2302e6f84a664a Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 12:19:07 -0700 Subject: [PATCH 05/12] Remove stale includes --- cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh | 3 --- 1 file changed, 3 deletions(-) diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index 1f436dbf0..d6fa8d5ea 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -16,7 +16,6 @@ #pragma once -#include "cuspatial_test/test_util.cuh" #include #include #include @@ -25,8 +24,6 @@ #include #include -#include - #include namespace cuspatial { From 4a822e53f56479764c3ce001c8f675b6a2726853 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 12:27:58 -0700 Subject: [PATCH 06/12] add documentation --- .../detail/find/find_and_combine_segment.cuh | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index d6fa8d5ea..6a0c27512 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -62,6 +62,14 @@ void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, } } +/** + * @brief Comparator for sorting the segment range. + * + * This comparator makes sure that the segment range are sorted by the following keys: + * 1. Segments with the same space id are grouped together. + * 2. Segments within the same space are grouped by their slope. + * 3. Within each slope group, segments are sorted by their lower left point. + */ template struct segment_comparator { bool __device__ operator()(thrust::tuple> const& lhs, @@ -89,6 +97,9 @@ struct segment_comparator { * @internal * @brief For each pair of mergeable segment, overwrites the first segment with merged result, * sets the flag for the second segment as 1. + * + * @note This function will alter the input segment range by rearranging the order of the segments + * within each space so that merging kernel can take place. */ template void find_and_combine_segment(OffsetRange offsets, From 19fc646693f033fb9c0ea31f1ec14ec8c4dddfe4 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 15:03:17 -0700 Subject: [PATCH 07/12] add test for overlapping and non-contiguous inputs --- .../find/find_and_combine_segments_test.cu | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/cpp/tests/find/find_and_combine_segments_test.cu b/cpp/tests/find/find_and_combine_segments_test.cu index 9905b53dd..764f0e678 100644 --- a/cpp/tests/find/find_and_combine_segments_test.cu +++ b/cpp/tests/find/find_and_combine_segments_test.cu @@ -325,3 +325,21 @@ TYPED_TEST(FindAndCombineSegmentsTest, twospaces_non_contiguous_segments_with_em S{P{2.0, 2.0}, P{3.0, 3.0}}, S{P{3.0, 3.0}, P{4.0, 4.0}}}); } + +TYPED_TEST(FindAndCombineSegmentsTest, onespace_non_contiguous_segments_overlaps) +{ + using T = TypeParam; + using index_t = std::size_t; + using P = vec_2d; + using S = segment; + + auto segments = make_segment_array( + {0, 3}, + {S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}, S{P{-1.0, -1.0}, P{4.0, 4.0}}}); + + CUSPATIAL_RUN_TEST( + this->run_single_test, + segments, + {0, 1, 1}, + {S{P{-1.0, -1.0}, P{5.0, 5.0}}, S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}}); +} From ef4685fbaeccc91317d3a62e0a5a722a68f76a99 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 16:54:24 -0700 Subject: [PATCH 08/12] initial fix for overflowing reduction bug --- .../intersection/linestring_intersection.cuh | 38 ++++++++++++++----- ...inestring_intersection_with_duplicates.cuh | 17 ++++++++- 2 files changed, 45 insertions(+), 10 deletions(-) diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh index c6c6e60ee..1a90ed6a1 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh @@ -227,6 +227,11 @@ linestring_intersection_result pairwise_linestring_intersection( auto num_points = points.num_geoms(); auto num_segments = segments.num_geoms(); + std::cout << "\n\n Points before merge: \n\n"; + points.debug_print(); + std::cout << "\n\n"; + + // Phase 3: Remove duplicate points from intermediates // TODO: improve memory usage by using IIFE to // Remove the duplicate points @@ -237,23 +242,24 @@ linestring_intersection_result pairwise_linestring_intersection( points.remove_if(range(point_flags.begin(), point_flags.end()), stream); if (segments.num_geoms() > 0) { - segments.debug_print(); + // segments.debug_print(); // Merge mergeable segments rmm::device_uvector segment_flags(num_segments, stream); detail::find_and_combine_segment( segments.offset_range(), segments.geom_range(), segment_flags.begin(), stream); - std::cout << "\n\n"; - rmm::device_uvector segment_flags_int(num_segments, stream); - thrust::copy(rmm::exec_policy(stream), - segment_flags.begin(), - segment_flags.end(), - segment_flags_int.begin()); - test::print_device_vector(segment_flags_int, "segment_flags"); - std::cout << "\n\n"; + // std::cout << "\n\n"; + // rmm::device_uvector segment_flags_int(num_segments, stream); + // thrust::copy(rmm::exec_policy(stream), + // segment_flags.begin(), + // segment_flags.end(), + // segment_flags_int.begin()); + // test::print_device_vector(segment_flags_int, "segment_flags"); + // std::cout << "\n\n"; segments.remove_if(range(segment_flags.begin(), segment_flags.end()), stream); + std::cout << "\n\n Segments after merge: \n"; segments.debug_print(); // Reusing `point_flags` for merge point on segment primitive. @@ -270,7 +276,21 @@ linestring_intersection_result pairwise_linestring_intersection( stream); points.remove_if(range(point_flags.begin(), point_flags.end()), stream); + + rmm::device_uvector point_flags_int(point_flags.size(), stream); + thrust::copy(rmm::exec_policy(stream), + point_flags.begin(), + point_flags.end(), + point_flags_int.begin()); + + std::cout << "\n\n" << "point_flags_nums: " << point_flags.size() << "\n"; + test::print_device_vector(point_flags_int, "\npoint_flags: "); } + + std::cout << "\n\n Points after merge: \n\n"; + points.debug_print(); + std::cout << "\n\n"; + // Phase 4: Assemble results as union column auto num_union_column_rows = points.geoms->size() + segments.geoms->size(); auto geometry_collection_offsets = diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index 2af03db64..eb36933c0 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -50,6 +50,18 @@ namespace detail { namespace intersection_functors { +/** + * @brief Cast `uint8_t` to `X` + * + * @tparam X The type to cast to + */ +template +struct uchar_to_x{ + + X __device__ operator()(uint8_t c) {return static_cast(c); } + +}; + /** @brief Functor to compute the updated offset buffer after `remove_if` operation. * * Given the `i`th row in the `geometry_collection_offset`, find the number of all @@ -292,11 +304,12 @@ struct linestring_intersection_intermediates { rmm::device_uvector reduced_flags(num_pairs(), stream); auto keys_begin = make_geometry_id_iterator(offsets->begin(), offsets->end()); + auto iflags = thrust::make_transform_iterator(flags.begin(), intersection_functors::uchar_to_x{}); auto [keys_end, flags_end] = thrust::reduce_by_key(rmm::exec_policy(stream), keys_begin, keys_begin + flags.size(), - flags.begin(), + iflags, reduced_keys.begin(), reduced_flags.begin(), thrust::equal_to(), @@ -310,6 +323,8 @@ struct linestring_intersection_intermediates { thrust::inclusive_scan( rmm::exec_policy(stream), reduced_flags.begin(), reduced_flags.end(), reduced_flags.begin()); + test::print_device_vector(reduced_flags, "\n\nreduced_flags: "); + // Update the offsets thrust::transform( rmm::exec_policy(stream), From f0000076fe6abfe926c081260152270bff7d6538 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 17:52:50 -0700 Subject: [PATCH 09/12] Remove stale debug prints --- .../detail/intersection/linestring_intersection.cuh | 12 ------------ .../linestring_intersection_with_duplicates.cuh | 12 ------------ 2 files changed, 24 deletions(-) diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh index c6c6e60ee..796365bde 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh @@ -237,25 +237,13 @@ linestring_intersection_result pairwise_linestring_intersection( points.remove_if(range(point_flags.begin(), point_flags.end()), stream); if (segments.num_geoms() > 0) { - segments.debug_print(); // Merge mergeable segments rmm::device_uvector segment_flags(num_segments, stream); detail::find_and_combine_segment( segments.offset_range(), segments.geom_range(), segment_flags.begin(), stream); - std::cout << "\n\n"; - rmm::device_uvector segment_flags_int(num_segments, stream); - thrust::copy(rmm::exec_policy(stream), - segment_flags.begin(), - segment_flags.end(), - segment_flags_int.begin()); - test::print_device_vector(segment_flags_int, "segment_flags"); - std::cout << "\n\n"; - segments.remove_if(range(segment_flags.begin(), segment_flags.end()), stream); - segments.debug_print(); - // Reusing `point_flags` for merge point on segment primitive. // Notice that `point_flags` contains leftovers from previous `find_duplicate_points` call. // Here it does not need to be zero initialized because find_points_on_segments will overwrite diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index 2af03db64..8e35dfdca 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -16,8 +16,6 @@ #pragma once -#include - #include #include #include @@ -363,16 +361,6 @@ struct linestring_intersection_intermediates { /// Return the number of geometries in the intermediates auto num_geoms() { return geoms->size(); } - - void debug_print() - { - test::print_device_vector(*offsets, "offsets: "); - test::print_device_vector(*geoms, "geoms: "); - test::print_device_vector(*lhs_linestring_ids, "lhs_linestring_ids: "); - test::print_device_vector(*lhs_segment_ids, "lhs_segment_ids: "); - test::print_device_vector(*rhs_linestring_ids, "rhs_linestring_ids: "); - test::print_device_vector(*rhs_segment_ids, "rhs_segment_ids: "); - } }; /** From 3ec56347ab6b3f1979d308027feec10a2ce3a964 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 17:53:02 -0700 Subject: [PATCH 10/12] Update documentation --- .../cuspatial/detail/find/find_and_combine_segment.cuh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh index 6a0c27512..b5ca12480 100644 --- a/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh +++ b/cpp/include/cuspatial/detail/find/find_and_combine_segment.cuh @@ -31,8 +31,8 @@ namespace detail { /** * @internal - * @brief Kernel to merge segments. Each thread works on a pair of segment spaces. - * naive n^2 algorithm. + * @brief Kernel to merge segments. Each thread works on one segment space, + * with a naive n^2 algorithm. */ template void __global__ simple_find_and_combine_segments_kernel(OffsetRange offsets, From 835a3276886218b6da498885591b4d2f338e9ef9 Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 29 Jun 2023 17:59:58 -0700 Subject: [PATCH 11/12] printf cleanup --- .../intersection/linestring_intersection.cuh | 18 ++---------------- ...linestring_intersection_with_duplicates.cuh | 13 +++++-------- 2 files changed, 7 insertions(+), 24 deletions(-) diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh index 603b2fc34..2db5492ed 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection.cuh @@ -227,11 +227,6 @@ linestring_intersection_result pairwise_linestring_intersection( auto num_points = points.num_geoms(); auto num_segments = segments.num_geoms(); - std::cout << "\n\n Points before merge: \n\n"; - points.debug_print(); - std::cout << "\n\n"; - - // Phase 3: Remove duplicate points from intermediates // TODO: improve memory usage by using IIFE to // Remove the duplicate points @@ -265,19 +260,10 @@ linestring_intersection_result pairwise_linestring_intersection( points.remove_if(range(point_flags.begin(), point_flags.end()), stream); rmm::device_uvector point_flags_int(point_flags.size(), stream); - thrust::copy(rmm::exec_policy(stream), - point_flags.begin(), - point_flags.end(), - point_flags_int.begin()); - - std::cout << "\n\n" << "point_flags_nums: " << point_flags.size() << "\n"; - test::print_device_vector(point_flags_int, "\npoint_flags: "); + thrust::copy( + rmm::exec_policy(stream), point_flags.begin(), point_flags.end(), point_flags_int.begin()); } - std::cout << "\n\n Points after merge: \n\n"; - points.debug_print(); - std::cout << "\n\n"; - // Phase 4: Assemble results as union column auto num_union_column_rows = points.geoms->size() + segments.geoms->size(); auto geometry_collection_offsets = diff --git a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh index 3dd5f535b..2784c8d1b 100644 --- a/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh +++ b/cpp/include/cuspatial/detail/intersection/linestring_intersection_with_duplicates.cuh @@ -53,11 +53,9 @@ namespace intersection_functors { * * @tparam X The type to cast to */ -template -struct uchar_to_x{ - - X __device__ operator()(uint8_t c) {return static_cast(c); } - +template +struct uchar_to_x { + X __device__ operator()(uint8_t c) { return static_cast(c); } }; /** @brief Functor to compute the updated offset buffer after `remove_if` operation. @@ -302,7 +300,8 @@ struct linestring_intersection_intermediates { rmm::device_uvector reduced_flags(num_pairs(), stream); auto keys_begin = make_geometry_id_iterator(offsets->begin(), offsets->end()); - auto iflags = thrust::make_transform_iterator(flags.begin(), intersection_functors::uchar_to_x{}); + auto iflags = + thrust::make_transform_iterator(flags.begin(), intersection_functors::uchar_to_x{}); auto [keys_end, flags_end] = thrust::reduce_by_key(rmm::exec_policy(stream), keys_begin, @@ -321,8 +320,6 @@ struct linestring_intersection_intermediates { thrust::inclusive_scan( rmm::exec_policy(stream), reduced_flags.begin(), reduced_flags.end(), reduced_flags.begin()); - test::print_device_vector(reduced_flags, "\n\nreduced_flags: "); - // Update the offsets thrust::transform( rmm::exec_policy(stream), From 3e046ebcff349ab13eed65cf8788541328ccd7ee Mon Sep 17 00:00:00 2001 From: Michael Wang Date: Thu, 27 Jul 2023 02:32:48 +0000 Subject: [PATCH 12/12] remove stale (and duplicate) test cases --- .../find/find_and_combine_segments_test.cu | 62 ------------------- 1 file changed, 62 deletions(-) diff --git a/cpp/tests/find/find_and_combine_segments_test.cu b/cpp/tests/find/find_and_combine_segments_test.cu index 98b3aa90c..f7a584f51 100644 --- a/cpp/tests/find/find_and_combine_segments_test.cu +++ b/cpp/tests/find/find_and_combine_segments_test.cu @@ -343,65 +343,3 @@ TYPED_TEST(FindAndCombineSegmentsTest, onespace_non_contiguous_segments_overlaps {0, 1, 1}, {S{P{-1.0, -1.0}, P{5.0, 5.0}}, S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}}); } - -TYPED_TEST(FindAndCombineSegmentsTest, twospaces) -{ - using T = TypeParam; - using index_t = std::size_t; - using P = vec_2d; - using S = segment; - - auto segments = make_segment_array({0, 2, 4}, - {S{P{0.0, 0.0}, P{1.0, 1.0}}, - S{P{1.0, 1.0}, P{2.0, 2.0}}, - S{P{1.0, 1.0}, P{0.0, 0.0}}, - S{P{2.0, 2.0}, P{1.0, 1.0}}}); - - CUSPATIAL_RUN_TEST(this->run_single_test, - segments, - {0, 1, 0, 1}, - {S{P{0.0, 0.0}, P{2.0, 2.0}}, - S{P{1.0, 1.0}, P{2.0, 2.0}}, - S{P{0.0, 0.0}, P{2.0, 2.0}}, - S{P{2.0, 2.0}, P{1.0, 1.0}}}); -} - -TYPED_TEST(FindAndCombineSegmentsTest, twospaces_non_contiguous_segments_with_empty) -{ - using T = TypeParam; - using index_t = std::size_t; - using P = vec_2d; - using S = segment; - - auto segments = make_segment_array({0, 4, 4}, - {S{P{1.0, 1.0}, P{2.0, 2.0}}, - S{P{3.0, 3.0}, P{4.0, 4.0}}, - S{P{0.0, 0.0}, P{1.0, 1.0}}, - S{P{2.0, 2.0}, P{3.0, 3.0}}}); - - CUSPATIAL_RUN_TEST(this->run_single_test, - segments, - {0, 1, 1, 1}, - {S{P{0.0, 0.0}, P{4.0, 4.0}}, - S{P{1.0, 1.0}, P{2.0, 2.0}}, - S{P{2.0, 2.0}, P{3.0, 3.0}}, - S{P{3.0, 3.0}, P{4.0, 4.0}}}); -} - -TYPED_TEST(FindAndCombineSegmentsTest, onespace_non_contiguous_segments_overlaps) -{ - using T = TypeParam; - using index_t = std::size_t; - using P = vec_2d; - using S = segment; - - auto segments = make_segment_array( - {0, 3}, - {S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}, S{P{-1.0, -1.0}, P{4.0, 4.0}}}); - - CUSPATIAL_RUN_TEST( - this->run_single_test, - segments, - {0, 1, 1}, - {S{P{-1.0, -1.0}, P{5.0, 5.0}}, S{P{1.0, 1.0}, P{2.0, 2.0}}, S{P{4.0, 4.0}, P{5.0, 5.0}}}); -}