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

Pairwise Multipoint Equals Count function #1022

Merged
Merged
Show file tree
Hide file tree
Changes from 14 commits
Commits
Show all changes
63 commits
Select commit Hold shift + click to select a range
96b28a3
Work on the most obvious parts of allpairs_points_equals_count
thomcom Mar 30, 2023
b8785f7
Build system.
thomcom Mar 30, 2023
c6e3910
Try a hand at copying point_polygon_distance_test.cu
thomcom Mar 30, 2023
45c128c
recording progress with Thomson
isVoid Mar 30, 2023
0f0a0d4
fix 0 sized input error
isVoid Mar 31, 2023
d1fb60c
Pass all tests.
thomcom Mar 31, 2023
da247f8
Switch to atomicAdd
thomcom Mar 31, 2023
2b7d7fa
Write one more test.
thomcom Mar 31, 2023
dd01d6c
using sort-then-search algorithm
isVoid Mar 31, 2023
b4ac329
Resolve merge
thomcom Mar 31, 2023
3dc6195
passes compilation!
isVoid Mar 31, 2023
9931ed1
Merge
thomcom Mar 31, 2023
dbd1bbf
Cleaning up for PR.
thomcom Mar 31, 2023
bd03668
Update docs, fix a typo.
thomcom Mar 31, 2023
313c020
Rename cpp test.
thomcom Mar 31, 2023
1c1e7ce
Strange test error.
thomcom Mar 31, 2023
28d5c13
Write python bindings.
thomcom Mar 31, 2023
6abb44e
Build python bindings and test.
thomcom Mar 31, 2023
c400646
Update cpp/include/cuspatial/experimental/detail/allpairs_multipoint_…
thomcom Mar 31, 2023
d2ac985
Update cpp/include/cuspatial/allpairs_multipoint_equals_count.hpp
thomcom Mar 31, 2023
23f4363
Update cpp/tests/experimental/spatial/allpairs_multipoint_equals_coun…
thomcom Mar 31, 2023
63eea9d
Add specific test.
thomcom Apr 3, 2023
29050fc
Merge branch 'feature/allpairs_point_equals_count' of github.com:thom…
thomcom Apr 3, 2023
30c9c86
refactors to multipoint-multipoint pairwise
isVoid Apr 5, 2023
2d64f3b
add missing files
isVoid Apr 5, 2023
f99810f
Get all tests passing.
thomcom Apr 5, 2023
7f606f9
Fix a bug in column wrapper.
thomcom Apr 6, 2023
c8ae2dd
Merge branch 'branch-23.04' into feature/allpairs_point_equals_count
thomcom Apr 6, 2023
ec24574
Make test untyped.:
thomcom Apr 6, 2023
b1f6207
Update docs
thomcom Apr 7, 2023
0050be0
Transfer python updates from later branch.
thomcom Apr 7, 2023
c178414
Improve .cpp file testing based on length requirement.
thomcom Apr 7, 2023
719d065
Tweak error message.
thomcom Apr 7, 2023
05090bb
Update equals_count docs and tests.
thomcom Apr 7, 2023
ca1218d
Minor docs tweak.
thomcom Apr 7, 2023
76c8aac
Remove repeat tests.
thomcom Apr 7, 2023
5c78146
Fix docs
thomcom Apr 7, 2023
e3aeac7
Merge branch 'branch-23.06' into feature/allpairs_point_equals_count
thomcom Apr 7, 2023
e0bba71
Merge branch 'branch-23.06' into feature/allpairs_point_equals_count
thomcom Apr 10, 2023
3d28ee9
Update cpp/include/cuspatial/experimental/detail/pairwise_multipoint_…
thomcom Apr 19, 2023
32050f9
Doc tweak
thomcom Apr 19, 2023
2420dfe
Merge branch 'feature/allpairs_point_equals_count' of github.com:thom…
thomcom Apr 19, 2023
ac9b755
Update cpp/include/cuspatial/pairwise_multipoint_equals_count.hpp
thomcom Apr 19, 2023
d904762
Update cpp/include/cuspatial/pairwise_multipoint_equals_count.hpp
thomcom Apr 19, 2023
102915b
Update python/cuspatial/cuspatial/core/binops/equals_count.py
thomcom Apr 19, 2023
72d6e97
Merge branch 'feature/allpairs_point_equals_count' of github.com:thom…
thomcom Apr 19, 2023
a806371
Merge branch 'branch-23.06' into feature/allpairs_point_equals_count
thomcom Apr 19, 2023
fbcd2bd
Update python/cuspatial/cuspatial/core/binops/equals_count.py
thomcom Apr 19, 2023
f7c2c98
Update cpp/include/cuspatial/experimental/pairwise_multipoint_equals_…
thomcom Apr 19, 2023
89a54c5
Address comment about multipoint_range docs.
thomcom Apr 19, 2023
37cba19
Merge branch 'feature/allpairs_point_equals_count' of github.com:thom…
thomcom Apr 19, 2023
e63c594
Tweaking because of format issue.
thomcom Apr 19, 2023
66498cf
Tweaking problem with docs.
thomcom Apr 19, 2023
ce1df18
Repair docs?
thomcom Apr 19, 2023
07401fe
CR at beginning of file typo
thomcom Apr 19, 2023
03bfc44
Handle Mark's last review comments.
thomcom Apr 26, 2023
da0baa5
Resolve merge conflict
thomcom Apr 26, 2023
3684b26
Merge branch 'branch-23.06' into feature/allpairs_point_equals_count
thomcom Apr 26, 2023
2b0c489
Accidentally didn't migrate one of the test files during merge.
thomcom Apr 26, 2023
cff14bd
Reflect new header paths in pairwise_multipoint_equals_count.
thomcom Apr 27, 2023
f66e2c4
Get pairwise_multipoint building.
thomcom Apr 27, 2023
19d5fce
Get rid of test file in wrong place, fix vec_2d lookup.
thomcom Apr 27, 2023
90fccc2
Merge branch 'branch-23.06' into feature/allpairs_point_equals_count
thomcom Apr 27, 2023
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 @@ -122,6 +122,7 @@ add_library(cuspatial
src/join/quadtree_point_in_polygon.cu
src/join/quadtree_point_to_nearest_linestring.cu
src/join/quadtree_bbox_filtering.cu
src/spatial/allpairs_multipoint_equals_count.cu
src/spatial/polygon_bounding_box.cu
src/spatial/linestring_bounding_box.cu
src/spatial/point_in_polygon.cu
Expand Down
62 changes: 62 additions & 0 deletions cpp/include/cuspatial/allpairs_multipoint_equals_count.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/*
* Copyright (c) 2019-2022, NVIDIA CORPORATION.
thomcom marked this conversation as resolved.
Show resolved Hide resolved
*
* 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/types.hpp>

#include <rmm/mr/device/per_device_resource.hpp>

#include <memory>

namespace cuspatial {

/**
* @addtogroup spatial
* @brief Compute the number of pairs of multipoints that are equal.
*
* Given two columns of interleaved multipoint coordinates, returns a column
* containing the count of points in each multipoint from `lhs` that are equal
* to a point in the corresponding multipoint in `rhs`.
*
* @param lhs Geometry column with a multipoint of interleaved coordinates
* @param rhs Geometry column with a multipoint of interleaved coordinates
* @param mr Device memory resource used to allocate the returned column.
* @return A column of size len(lhs) containing the count that each point of
* the multipoint in `lhs` is equal to a point in `rhs`.
*
* @throw cuspatial::logic_error if `lhs` and `rhs` have different coordinate
* types.
*
* @example
* ```
* lhs: 0, 0, 1, 1, 2, 2
* rhs: 0, 0, 1, 1, 2, 2
* result: 1, 1, 1
*
* lhs: 0, 0, 1, 1, 2, 2
* rhs: 0, 0
* result: 1, 0, 0
*/

/**
*/
std::unique_ptr<cudf::column> allpairs_multipoint_equals_count(
cudf::column_view const& lhs,
cudf::column_view const& rhs,
rmm::mr::device_memory_resource* mr = rmm::mr::get_current_device_resource());

} // namespace cuspatial
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2023, 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 <cuspatial/vec_2d.hpp>

#include <rmm/cuda_stream_view.hpp>

#include <iterator>

namespace cuspatial {

/**
* @brief Compute the number of multipoint pairs that are equal.
thomcom marked this conversation as resolved.
Show resolved Hide resolved
*
* Given two sets of multipoints, each represented by a range of `vec_2d<T>`s,
thomcom marked this conversation as resolved.
Show resolved Hide resolved
* computes the number of pairs of multipoints that are equal. Example:
*
* ```
* lhs: { {0, 0}, {1, 1}, {2, 2} }
* rhs: { {0, 0}, {1, 1}, {2, 2} }
* count: { 1, 1, 1 }
thomcom marked this conversation as resolved.
Show resolved Hide resolved
*
* lhs: { {0, 0} }
* rhs: { {0, 0}, {1, 1}, {2, 2}, {3, 3} }
thomcom marked this conversation as resolved.
Show resolved Hide resolved
* count: { 1 }
*
* lhs: { {0, 0}, {1, 1}, {2, 2}, {3, 3} }
* rhs: { {0, 0} }
* count: { 1, 0, 0, 0 }
* ```
*
* @note All input iterators must have a `value_type` of `cuspatial::vec_2d<T>`
* and the output iterator must be able to accept for storage values of type
* `uint32_t`.
*
* @param[in] lhs_first multipoint_ref of first set of points
* @param[in] rhs_first multipoint_ref of second set of points
* @param[out] count_first: beginning of range of uint32_t counts
* @param[in] stream: The CUDA stream on which to perform computations and allocate memory.
*
* @tparam MultiPointRefA Iterator over multipoint vec_2ds. Must meet the requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam MultiPointRefB Iterator over multipoint vec_2ds. Must meet the requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible.
* @tparam OutputIt Iterator over uint32_t. Must meet the requirements of
* [LegacyRandomAccessIterator][LinkLRAI] and be device-accessible and mutable.
*
* @return Output iterator to the element past the last count result written.
*
* [LinkLRAI]: https://en.cppreference.com/w/cpp/named_req/RandomAccessIterator
* "LegacyRandomAccessIterator"
*/
template <class MultiPointRefA, class MultiPointRefB, class OutputIt>
OutputIt allpairs_multipoint_equals_count(MultiPointRefA const& lhs_first,
MultiPointRefB const& rhs_first,
OutputIt count_first,
rmm::cuda_stream_view stream = rmm::cuda_stream_default);

} // namespace cuspatial

#include <cuspatial/experimental/detail/allpairs_multipoint_equals_count.cuh>
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* Copyright (c) 2022, NVIDIA CORPORATION.
thomcom marked this conversation as resolved.
Show resolved Hide resolved
*
* 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 <cuspatial/constants.hpp>
#include <cuspatial/cuda_utils.hpp>
#include <cuspatial/detail/utility/zero_data.cuh>
#include <cuspatial/error.hpp>
#include <cuspatial/experimental/ranges/range.cuh>
#include <cuspatial/traits.hpp>
#include <cuspatial/vec_2d.hpp>

#include <rmm/cuda_stream_view.hpp>
#include <rmm/device_uvector.hpp>
#include <rmm/exec_policy.hpp>

#include <thrust/binary_search.h>
#include <thrust/sort.h>
#include <thrust/transform.h>

#include <iterator>
#include <type_traits>

namespace cuspatial {

template <class MultiPointRefA, class MultiPointRefB, class OutputIt>
OutputIt allpairs_multipoint_equals_count(MultiPointRefA const& lhs,
MultiPointRefB const& rhs,
OutputIt output,
rmm::cuda_stream_view stream)
{
using T = typename MultiPointRefA::point_t::value_type;

static_assert(is_same_floating_point<T, typename MultiPointRefB::point_t::value_type>(),
"Origin and input must have the same base floating point type.");

if (lhs.size() == 0) return output;

if (rhs.size() == 0) {
detail::zero_data_async(output, output + lhs.size(), stream);
return output + lhs.size();
}

// Create a sorted copy of the rhs points.
rmm::device_uvector<vec_2d<T>> rhs_sorted(rhs.size(), stream);
thrust::copy(rmm::exec_policy(stream), rhs.begin(), rhs.end(), rhs_sorted.begin());
thrust::sort(rmm::exec_policy(stream), rhs_sorted.begin(), rhs_sorted.end());

// For each point in the lhs, count the number of points in the rhs that are equal.
return thrust::transform(
rmm::exec_policy(stream),
lhs.begin(),
lhs.end(),
output,
[rhs_sorted_range = range(rhs_sorted.begin(), rhs_sorted.end())] __device__(auto lhs_point) {
auto [lower_it, upper_it] = thrust::equal_range(
thrust::seq, rhs_sorted_range.cbegin(), rhs_sorted_range.cend(), lhs_point);
return thrust::distance(lower_it, upper_it);
});
}

} // namespace cuspatial
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
#pragma once
#include <cuspatial/cuda_utils.hpp>
#include <cuspatial/detail/iterator.hpp>

#include <thrust/distance.h>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ namespace cuspatial {
*/
template <typename VecIterator>
class multipoint_ref {
public:
using point_t = iterator_value_type<VecIterator>;

public:
CUSPATIAL_HOST_DEVICE multipoint_ref(VecIterator begin, VecIterator end);

/// Return iterator to the starting point of the multipoint.
Expand Down
4 changes: 4 additions & 0 deletions cpp/include/cuspatial/experimental/ranges/range.cuh
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ class range {
auto CUSPATIAL_HOST_DEVICE begin() { return _begin; }
/// Return the end iterator to the range
auto CUSPATIAL_HOST_DEVICE end() { return _end; }
/// Return the start const iterator to the range
auto CUSPATIAL_HOST_DEVICE cbegin() const { return _begin; }
/// Return the end const iterator to the range
auto CUSPATIAL_HOST_DEVICE cend() const { return _end; }
thomcom marked this conversation as resolved.
Show resolved Hide resolved
/// Return the size of the range
auto CUSPATIAL_HOST_DEVICE size() { return thrust::distance(_begin, _end); }

Expand Down
8 changes: 4 additions & 4 deletions cpp/include/cuspatial_test/base_fixture.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
* limitations under the License.
*/

#pragma once

#include <rmm/cuda_stream_view.hpp>
#include <rmm/mr/device/per_device_resource.hpp>

Expand Down Expand Up @@ -54,8 +56,7 @@ class RMMResourceMixin {
* class MyTestFixture : public cuspatial::test::BaseFixture {};
* ```
*/
class BaseFixture : public RMMResourceMixin, public ::testing::Test {
};
class BaseFixture : public RMMResourceMixin, public ::testing::Test {};

/**
* @brief Base test fixture class from which libcuspatial test with only value parameterization
Expand All @@ -79,8 +80,7 @@ class BaseFixture : public RMMResourceMixin, public ::testing::Test {
*/
template <typename... Ts>
class BaseFixtureWithParam : public RMMResourceMixin,
public ::testing::TestWithParam<std::tuple<Ts...>> {
};
public ::testing::TestWithParam<std::tuple<Ts...>> {};

} // namespace test
} // namespace cuspatial
98 changes: 98 additions & 0 deletions cpp/src/spatial/allpairs_multipoint_equals_count.cu
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
/*
* Copyright (c) 2023, 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.
*/

#include <cuspatial/error.hpp>
#include <cuspatial/experimental/allpairs_multipoint_equals_count.cuh>
#include <cuspatial/experimental/geometry_collection/multipoint_ref.cuh>
#include <cuspatial/experimental/iterator_factory.cuh>
#include <cuspatial/vec_2d.hpp>

#include <cudf/column/column.hpp>
#include <cudf/column/column_device_view.cuh>
#include <cudf/column/column_factories.hpp>
#include <cudf/utilities/type_dispatcher.hpp>

#include <rmm/cuda_stream_view.hpp>
#include <rmm/exec_policy.hpp>

#include <thrust/iterator/zip_iterator.h>
#include <thrust/pair.h>
#include <thrust/transform.h>
#include <thrust/tuple.h>

#include <type_traits>
#include <utility>

namespace cuspatial {
namespace detail {
namespace {

struct dispatch_allpairs_multipoint_equals_count {
template <typename T, typename... Args>
std::enable_if_t<not std::is_floating_point<T>::value, std::unique_ptr<cudf::column>> operator()(
Args&&...)
{
CUSPATIAL_FAIL("Non-floating point operation is not supported");
}

template <typename T>
std::enable_if_t<std::is_floating_point<T>::value, std::unique_ptr<cudf::column>> operator()(
cudf::column_view const& lhs,
cudf::column_view const& rhs,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr)
{
auto size = lhs.size();
auto type = cudf::data_type(cudf::type_to_id<uint32_t>());

auto result =
cudf::make_fixed_width_column(type, size, cudf::mask_state::UNALLOCATED, stream, mr);

auto lhs_iterator = make_vec_2d_iterator(lhs.begin<T>());
auto rhs_iterator = make_vec_2d_iterator(rhs.begin<T>());
auto lhs_ref = multipoint_ref(lhs_iterator, lhs_iterator + lhs.size() / 2);
auto rhs_ref = multipoint_ref(rhs_iterator, rhs_iterator + rhs.size() / 2);

cuspatial::allpairs_multipoint_equals_count(
lhs_ref, rhs_ref, result->mutable_view().begin<uint32_t>(), stream);

return result;
}
};

} // namespace

std::unique_ptr<cudf::column> allpairs_multipoint_equals_count(cudf::column_view const& lhs,
cudf::column_view const& rhs,
rmm::cuda_stream_view stream,
rmm::mr::device_memory_resource* mr)
{
CUSPATIAL_EXPECTS(lhs.type() == rhs.type(), "Column type mismatch");

return cudf::type_dispatcher(
lhs.type(), dispatch_allpairs_multipoint_equals_count(), lhs, rhs, stream, mr);
}

} // namespace detail

std::unique_ptr<cudf::column> allpairs_multipoint_equals_count(cudf::column_view const& lhs,
cudf::column_view const& rhs,
rmm::mr::device_memory_resource* mr)
{
return detail::allpairs_multipoint_equals_count(lhs, rhs, rmm::cuda_stream_default, mr);
}

} // namespace cuspatial
Loading